@reddoorla/maintenance 0.97.0 → 0.98.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{announce-5ZD2SBGD.js → announce-2FH2KBQQ.js} +4 -4
- package/dist/{bump-deps-775VLDYB.js → bump-deps-54K4ECP3.js} +2 -2
- package/dist/{chunk-YXWBM26P.js → chunk-3YALLSBF.js} +2 -2
- package/dist/{chunk-LAJ3FF54.js → chunk-5UI4FERC.js} +16 -5
- package/dist/chunk-5UI4FERC.js.map +1 -0
- package/dist/{chunk-VMGHQUTV.js → chunk-B2BRFWJY.js} +2 -2
- package/dist/{chunk-IOTOOTII.js → chunk-CP6MVZ5X.js} +16 -1
- package/dist/{chunk-IOTOOTII.js.map → chunk-CP6MVZ5X.js.map} +1 -1
- package/dist/{chunk-L3S3QZXL.js → chunk-DXZRWW2F.js} +64 -9
- package/dist/chunk-DXZRWW2F.js.map +1 -0
- package/dist/chunk-DZZ5KRTB.js +23 -0
- package/dist/chunk-DZZ5KRTB.js.map +1 -0
- package/dist/{chunk-U2ZI6G7H.js → chunk-GRF2RYEO.js} +2 -2
- package/dist/{chunk-QFSL2L2B.js → chunk-L5F3WYIY.js} +81 -31
- package/dist/chunk-L5F3WYIY.js.map +1 -0
- package/dist/{chunk-MMSMZC7S.js → chunk-MNRWHSFS.js} +2 -2
- package/dist/{chunk-PARKXDXI.js → chunk-ORTOMEYR.js} +2 -2
- package/dist/{chunk-FP6HOW6J.js → chunk-S2PLX4XK.js} +2 -2
- package/dist/{chunk-A5QKNOXW.js → chunk-TTT6HYPW.js} +47 -10
- package/dist/chunk-TTT6HYPW.js.map +1 -0
- package/dist/{chunk-BIYQN7FH.js → chunk-VCPTOZ56.js} +31 -1
- package/dist/{chunk-BIYQN7FH.js.map → chunk-VCPTOZ56.js.map} +1 -1
- package/dist/{chunk-LDHRIQUW.js → chunk-ZEE5WQYU.js} +2 -2
- package/dist/cli/bin.js +27 -27
- package/dist/cli/commands/audit.js +10 -10
- package/dist/client-3XGSZMLU.js +11 -0
- package/dist/{convert-to-pnpm-KLWA53N5.js → convert-to-pnpm-U2CRNKNY.js} +2 -2
- package/dist/{db-II5WAK4D.js → db-7XYTBIPH.js} +20 -13
- package/dist/db-7XYTBIPH.js.map +1 -0
- package/dist/{deadletter-G4M3HSVM.js → deadletter-A7RQVNG3.js} +8 -4
- package/dist/{digest-CWKK2DMR.js → digest-AMXRGWZA.js} +20 -20
- package/dist/{digest-collectors-CYTN2EUX.js → digest-collectors-CX2NCGS7.js} +7 -7
- package/dist/{ensure-site-2QZHFVQ3.js → ensure-site-F2WFCWWA.js} +2 -2
- package/dist/{forms-notify-target-X6UEOI2M.js → forms-notify-target-DK5R326N.js} +3 -3
- package/dist/{github-signals-QIRTHHET.js → github-signals-RGRPYTUB.js} +6 -6
- package/dist/{header-image-H7ZJAV26.js → header-image-43ZIEJKP.js} +3 -3
- package/dist/{health-endpoint-BJ6BKRHF.js → health-endpoint-K5LXDPGE.js} +2 -2
- package/dist/{health-mirror-KU3G7V2Y.js → health-mirror-WZUHWCCV.js} +3 -3
- package/dist/index.js +10 -11
- package/dist/index.js.map +1 -1
- package/dist/{init-GOWDA5QS.js → init-OFITGMOP.js} +5 -5
- package/dist/{launch-7N3X2MXB.js → launch-AJY3TGTQ.js} +7 -7
- package/dist/{lighthouse-52WSPZ5D.js → lighthouse-RFMFREEX.js} +2 -2
- package/dist/{match-harness-GBCDSVPS.js → match-harness-CFELJA57.js} +2 -2
- package/dist/migrate-EZL55AWA.js +7 -0
- package/dist/{onboard-JQQIMQW7.js → onboard-F7RTLMDZ.js} +2 -2
- package/dist/{orchestrate-L2A5BZFY.js → orchestrate-SAIFXZIW.js} +5 -5
- package/dist/{pipeline-UUPXOS2J.js → pipeline-TCSNVDQZ.js} +3 -3
- package/dist/{preflight-O7Q6FWHU.js → preflight-6XGVVO2U.js} +7 -7
- package/dist/{prismic-ci-NAPWOXXD.js → prismic-ci-XMX7A5E4.js} +2 -2
- package/dist/{prismic-models-LL6ORTQ2.js → prismic-models-7GKFAAFA.js} +4 -4
- package/dist/prospect/types.d.ts +44 -2
- package/dist/prospect/types.js +1 -1
- package/dist/{prospect-audit-FMPGQIRQ.js → prospect-audit-KWP5P5U2.js} +37 -5
- package/dist/prospect-audit-KWP5P5U2.js.map +1 -0
- package/dist/{render-MHUUHPLN.js → render-NWUAX6RN.js} +3 -3
- package/dist/{renovate-dispatch-2IHAZDVA.js → renovate-dispatch-ZZQXT7DA.js} +2 -2
- package/dist/replay-HB44TAII.js +77 -0
- package/dist/replay-HB44TAII.js.map +1 -0
- package/dist/{report-IAHXN5CW.js → report-MVPWS7WP.js} +13 -13
- package/dist/{report-mirror-4QM57LMS.js → report-mirror-O6IDFDWU.js} +3 -3
- package/dist/{roster-GDNSIRAK.js → roster-EJ3ILR52.js} +2 -2
- package/dist/{screenouts-7P5GOZMV.js → screenouts-7NQUWHOJ.js} +14 -1
- package/dist/screenouts-7NQUWHOJ.js.map +1 -0
- package/dist/{self-updating-ZUWPGYUP.js → self-updating-KX5FMGEO.js} +2 -2
- package/dist/{selftest-G4W3LIBQ.js → selftest-KABY2CYJ.js} +5 -5
- package/dist/{site-mirror-WR7ACXOV.js → site-mirror-TKTDWYP3.js} +3 -3
- package/dist/{smoke-suite-WAUPI6EJ.js → smoke-suite-QQMV7TNA.js} +2 -2
- package/dist/{submissions-JDZP35JM.js → submissions-4I66W6QK.js} +11 -1
- package/dist/{submissions-JDZP35JM.js.map → submissions-4I66W6QK.js.map} +1 -1
- package/dist/{submissions-2SHCFOKD.js → submissions-K5UXGZUN.js} +4 -4
- package/dist/{svelte-codemods-VOLOKKFI.js → svelte-codemods-YFN4TEGV.js} +2 -2
- package/dist/{sync-configs-OXSWKVZ2.js → sync-configs-HBXS3D7C.js} +2 -2
- package/dist/{upgrade-EVAL3JTO.js → upgrade-XOJMDIT4.js} +2 -2
- package/package.json +1 -1
- package/dist/chunk-A5QKNOXW.js.map +0 -1
- package/dist/chunk-L3S3QZXL.js.map +0 -1
- package/dist/chunk-LAJ3FF54.js.map +0 -1
- package/dist/chunk-QFSL2L2B.js.map +0 -1
- package/dist/client-DGTO65WB.js +0 -11
- package/dist/db-II5WAK4D.js.map +0 -1
- package/dist/migrate-XZ7U5DFC.js +0 -7
- package/dist/prospect-audit-FMPGQIRQ.js.map +0 -1
- package/dist/replay-4FVFOMHH.js +0 -54
- package/dist/replay-4FVFOMHH.js.map +0 -1
- package/dist/screenouts-7P5GOZMV.js.map +0 -1
- /package/dist/{announce-5ZD2SBGD.js.map → announce-2FH2KBQQ.js.map} +0 -0
- /package/dist/{bump-deps-775VLDYB.js.map → bump-deps-54K4ECP3.js.map} +0 -0
- /package/dist/{chunk-YXWBM26P.js.map → chunk-3YALLSBF.js.map} +0 -0
- /package/dist/{chunk-VMGHQUTV.js.map → chunk-B2BRFWJY.js.map} +0 -0
- /package/dist/{chunk-U2ZI6G7H.js.map → chunk-GRF2RYEO.js.map} +0 -0
- /package/dist/{chunk-MMSMZC7S.js.map → chunk-MNRWHSFS.js.map} +0 -0
- /package/dist/{chunk-PARKXDXI.js.map → chunk-ORTOMEYR.js.map} +0 -0
- /package/dist/{chunk-FP6HOW6J.js.map → chunk-S2PLX4XK.js.map} +0 -0
- /package/dist/{chunk-LDHRIQUW.js.map → chunk-ZEE5WQYU.js.map} +0 -0
- /package/dist/{client-DGTO65WB.js.map → client-3XGSZMLU.js.map} +0 -0
- /package/dist/{convert-to-pnpm-KLWA53N5.js.map → convert-to-pnpm-U2CRNKNY.js.map} +0 -0
- /package/dist/{deadletter-G4M3HSVM.js.map → deadletter-A7RQVNG3.js.map} +0 -0
- /package/dist/{digest-CWKK2DMR.js.map → digest-AMXRGWZA.js.map} +0 -0
- /package/dist/{digest-collectors-CYTN2EUX.js.map → digest-collectors-CX2NCGS7.js.map} +0 -0
- /package/dist/{ensure-site-2QZHFVQ3.js.map → ensure-site-F2WFCWWA.js.map} +0 -0
- /package/dist/{forms-notify-target-X6UEOI2M.js.map → forms-notify-target-DK5R326N.js.map} +0 -0
- /package/dist/{github-signals-QIRTHHET.js.map → github-signals-RGRPYTUB.js.map} +0 -0
- /package/dist/{header-image-H7ZJAV26.js.map → header-image-43ZIEJKP.js.map} +0 -0
- /package/dist/{health-endpoint-BJ6BKRHF.js.map → health-endpoint-K5LXDPGE.js.map} +0 -0
- /package/dist/{health-mirror-KU3G7V2Y.js.map → health-mirror-WZUHWCCV.js.map} +0 -0
- /package/dist/{init-GOWDA5QS.js.map → init-OFITGMOP.js.map} +0 -0
- /package/dist/{launch-7N3X2MXB.js.map → launch-AJY3TGTQ.js.map} +0 -0
- /package/dist/{lighthouse-52WSPZ5D.js.map → lighthouse-RFMFREEX.js.map} +0 -0
- /package/dist/{match-harness-GBCDSVPS.js.map → match-harness-CFELJA57.js.map} +0 -0
- /package/dist/{migrate-XZ7U5DFC.js.map → migrate-EZL55AWA.js.map} +0 -0
- /package/dist/{onboard-JQQIMQW7.js.map → onboard-F7RTLMDZ.js.map} +0 -0
- /package/dist/{orchestrate-L2A5BZFY.js.map → orchestrate-SAIFXZIW.js.map} +0 -0
- /package/dist/{pipeline-UUPXOS2J.js.map → pipeline-TCSNVDQZ.js.map} +0 -0
- /package/dist/{preflight-O7Q6FWHU.js.map → preflight-6XGVVO2U.js.map} +0 -0
- /package/dist/{prismic-ci-NAPWOXXD.js.map → prismic-ci-XMX7A5E4.js.map} +0 -0
- /package/dist/{prismic-models-LL6ORTQ2.js.map → prismic-models-7GKFAAFA.js.map} +0 -0
- /package/dist/{render-MHUUHPLN.js.map → render-NWUAX6RN.js.map} +0 -0
- /package/dist/{renovate-dispatch-2IHAZDVA.js.map → renovate-dispatch-ZZQXT7DA.js.map} +0 -0
- /package/dist/{report-IAHXN5CW.js.map → report-MVPWS7WP.js.map} +0 -0
- /package/dist/{report-mirror-4QM57LMS.js.map → report-mirror-O6IDFDWU.js.map} +0 -0
- /package/dist/{roster-GDNSIRAK.js.map → roster-EJ3ILR52.js.map} +0 -0
- /package/dist/{self-updating-ZUWPGYUP.js.map → self-updating-KX5FMGEO.js.map} +0 -0
- /package/dist/{selftest-G4W3LIBQ.js.map → selftest-KABY2CYJ.js.map} +0 -0
- /package/dist/{site-mirror-WR7ACXOV.js.map → site-mirror-TKTDWYP3.js.map} +0 -0
- /package/dist/{smoke-suite-WAUPI6EJ.js.map → smoke-suite-QQMV7TNA.js.map} +0 -0
- /package/dist/{submissions-2SHCFOKD.js.map → submissions-K5UXGZUN.js.map} +0 -0
- /package/dist/{svelte-codemods-VOLOKKFI.js.map → svelte-codemods-YFN4TEGV.js.map} +0 -0
- /package/dist/{sync-configs-OXSWKVZ2.js.map → sync-configs-HBXS3D7C.js.map} +0 -0
- /package/dist/{upgrade-EVAL3JTO.js.map → upgrade-XOJMDIT4.js.map} +0 -0
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
// src/prospect/daily-cap.ts
|
|
2
|
+
var PROSPECT_AUDIT_DAILY_CAP = 25;
|
|
3
|
+
var DAILY_CAP_LOOKBACK = PROSPECT_AUDIT_DAILY_CAP * 2;
|
|
4
|
+
var DAY_MS = 24 * 60 * 60 * 1e3;
|
|
5
|
+
function countAuditsInDailyWindow(recent, now) {
|
|
6
|
+
const dayAgo = now.getTime() - DAY_MS;
|
|
7
|
+
return recent.filter((r) => Date.parse(r.created_at) >= dayAgo).length;
|
|
8
|
+
}
|
|
9
|
+
function isOverDailyCap(count) {
|
|
10
|
+
return count >= PROSPECT_AUDIT_DAILY_CAP;
|
|
11
|
+
}
|
|
12
|
+
function dailyCapMessage(count, cap = PROSPECT_AUDIT_DAILY_CAP) {
|
|
13
|
+
return `${count} audits have run in the last 24 hours (cap ${cap}). This is a runaway brake \u2014 if the run is genuinely needed, raise PROSPECT_AUDIT_DAILY_CAP.`;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export {
|
|
17
|
+
PROSPECT_AUDIT_DAILY_CAP,
|
|
18
|
+
DAILY_CAP_LOOKBACK,
|
|
19
|
+
countAuditsInDailyWindow,
|
|
20
|
+
isOverDailyCap,
|
|
21
|
+
dailyCapMessage
|
|
22
|
+
};
|
|
23
|
+
//# sourceMappingURL=chunk-DZZ5KRTB.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/prospect/daily-cap.ts"],"sourcesContent":["/**\n * The prospect-audit runaway brake — the numbers and the arithmetic, in one\n * place both callers reach.\n *\n * It lived inside `src/dashboard/prospect-audit-trigger.ts`, which meant it\n * guarded the dashboard dispatch path and nothing else, while every batch to\n * date — including the 29-site corpus — went through `prospect-audit` on the\n * CLI, which had no cap at all (MED-15 of the 2026-09-02 review).\n *\n * That is the same shape #618 already fixed once in this feature, and said so\n * in `src/cli/commands/prospect-audit.ts` while fixing it: *\"The sole private-\n * address guard was in `triggerProspectAudit` — one layer at the far end of the\n * chain — so anyone running the CLI directly, or any future second caller, had\n * none.\"* Identical sentence, different guard.\n *\n * Dependency-free on purpose: the CLI's command modules are lazily loaded and\n * must not drag the GitHub/dispatch layer in behind a constant, and the count\n * needs nothing from a row but its timestamp.\n */\n\n/** Anything with a creation timestamp — `ProspectAuditListItem` satisfies it.\n * Structural so this module needs no import from `src/db`. */\nexport type DatedAudit = { created_at: string };\n\n/** Most audits that may be STARTED in any rolling 24 hours (#612 review).\n *\n * The duplicate window stops the SAME url being re-run; nothing stopped\n * DISTINCT urls. One authenticated session could dispatch ~30/minute against\n * 30 hostnames indefinitely, and one audit is structurally an Opus call plus\n * up to 28 Sonnet calls with up to 112 billed web searches, a 20-page double\n * crawl, a 3-pass Lighthouse and a PDF render, inside a billed Actions job.\n *\n * 25/day is far above real use (this is one operator clicking a button) and far\n * below a number that could quietly cost hundreds. A cap that never binds in\n * normal operation is the point: it is a runaway brake, not a quota. */\nexport const PROSPECT_AUDIT_DAILY_CAP = 25;\n\n/** Lookback for the daily cap. Must exceed the cap so the count can actually\n * reach it — a lookback at or below the cap would make the limit unreachable\n * and the brake permanently disengaged, which is exactly the kind of guard\n * that reads as working while doing nothing. */\nexport const DAILY_CAP_LOOKBACK = PROSPECT_AUDIT_DAILY_CAP * 2;\n\n/** The rolling window itself. */\nconst DAY_MS = 24 * 60 * 60 * 1000;\n\n/** How many of `recent` were created in the 24 hours before `now`.\n *\n * `recent` is expected to be the newest `DAILY_CAP_LOOKBACK` audits; the\n * caller does the fetching so this stays pure and testable from either side. */\nexport function countAuditsInDailyWindow(recent: readonly DatedAudit[], now: Date): number {\n const dayAgo = now.getTime() - DAY_MS;\n return recent.filter((r) => Date.parse(r.created_at) >= dayAgo).length;\n}\n\n/** Whether that count trips the brake. */\nexport function isOverDailyCap(count: number): boolean {\n return count >= PROSPECT_AUDIT_DAILY_CAP;\n}\n\n/** The refusal, worded once so the dashboard's 429 body and the CLI's stderr\n * say the same thing. Carries both numbers: a bare \"refused\" leaves the\n * operator guessing whether they hit a limit or broke something. */\nexport function dailyCapMessage(count: number, cap: number = PROSPECT_AUDIT_DAILY_CAP): string {\n return `${count} audits have run in the last 24 hours (cap ${cap}). This is a runaway brake — if the run is genuinely needed, raise PROSPECT_AUDIT_DAILY_CAP.`;\n}\n"],"mappings":";AAmCO,IAAM,2BAA2B;AAMjC,IAAM,qBAAqB,2BAA2B;AAG7D,IAAM,SAAS,KAAK,KAAK,KAAK;AAMvB,SAAS,yBAAyB,QAA+B,KAAmB;AACzF,QAAM,SAAS,IAAI,QAAQ,IAAI;AAC/B,SAAO,OAAO,OAAO,CAAC,MAAM,KAAK,MAAM,EAAE,UAAU,KAAK,MAAM,EAAE;AAClE;AAGO,SAAS,eAAe,OAAwB;AACrD,SAAO,SAAS;AAClB;AAKO,SAAS,gBAAgB,OAAe,MAAc,0BAAkC;AAC7F,SAAO,GAAG,KAAK,8CAA8C,GAAG;AAClE;","names":[]}
|
|
@@ -26,7 +26,7 @@ import {
|
|
|
26
26
|
} from "./chunk-LUF52EIY.js";
|
|
27
27
|
import {
|
|
28
28
|
runAudits
|
|
29
|
-
} from "./chunk-
|
|
29
|
+
} from "./chunk-DXZRWW2F.js";
|
|
30
30
|
import {
|
|
31
31
|
siteLabel
|
|
32
32
|
} from "./chunk-XXTZBPUY.js";
|
|
@@ -161,4 +161,4 @@ export {
|
|
|
161
161
|
DEFAULT_INIT_STEPS,
|
|
162
162
|
init
|
|
163
163
|
};
|
|
164
|
-
//# sourceMappingURL=chunk-
|
|
164
|
+
//# sourceMappingURL=chunk-GRF2RYEO.js.map
|
|
@@ -2,6 +2,7 @@ import {
|
|
|
2
2
|
AI_AGENTS,
|
|
3
3
|
CLASSICAL_AGENTS,
|
|
4
4
|
USER_AGENT,
|
|
5
|
+
anchorsTruncated,
|
|
5
6
|
buildJourney,
|
|
6
7
|
canonicalizeUrl,
|
|
7
8
|
crawlSite,
|
|
@@ -16,7 +17,7 @@ import {
|
|
|
16
17
|
sleep,
|
|
17
18
|
summarizeAccessibility,
|
|
18
19
|
usablePages
|
|
19
|
-
} from "./chunk-
|
|
20
|
+
} from "./chunk-5UI4FERC.js";
|
|
20
21
|
import {
|
|
21
22
|
checkGoal
|
|
22
23
|
} from "./chunk-T7ZUUOZ2.js";
|
|
@@ -26,8 +27,12 @@ import {
|
|
|
26
27
|
|
|
27
28
|
// src/prospect/consistency.ts
|
|
28
29
|
var PHONE_IN_TEXT = /(?<!\d)(?:\+?1[\s.-]?)?\(?\d{3}\)?[\s.-]?\d{3}[\s.-]?\d{4}(?!\d)/g;
|
|
29
|
-
var
|
|
30
|
-
var
|
|
30
|
+
var NAME_GAP = "(?:[\\s.,&'\u2019-]*[A-Z][A-Za-z.'\u2019&-]{0,19}){0,6}[\\s.,&'\u2019-]*";
|
|
31
|
+
var COPYRIGHT_YEAR = new RegExp(
|
|
32
|
+
`(?:\xA9|&[Cc]opy;|©|[Cc]opyright|COPYRIGHT)(${NAME_GAP})(?:(\\d{4})\\s*[-\u2013\u2014]\\s*)?(\\d{4})`,
|
|
33
|
+
"g"
|
|
34
|
+
);
|
|
35
|
+
var SENTENCE_BREAK = /[.!?]\s+[A-Z]/;
|
|
31
36
|
function normalizePhone(raw) {
|
|
32
37
|
const digits = raw.replace(/\D/g, "");
|
|
33
38
|
const national = digits.length === 11 && digits.startsWith("1") ? digits.slice(1) : digits;
|
|
@@ -66,9 +71,12 @@ function checkConsistency(pages) {
|
|
|
66
71
|
record(emails, address.toLowerCase(), address, page.url, true);
|
|
67
72
|
continue;
|
|
68
73
|
}
|
|
69
|
-
|
|
74
|
+
const abs = resolveNavigable(href, page.url);
|
|
75
|
+
if (!abs) continue;
|
|
76
|
+
const key = canonicalizeUrl(abs);
|
|
77
|
+
if (key) hrefs.add(key);
|
|
70
78
|
}
|
|
71
|
-
linkSets.push({ url: page.url, hrefs });
|
|
79
|
+
linkSets.push({ url: page.url, hrefs, truncated: anchorsTruncated(extract) });
|
|
72
80
|
for (const match of extract.text.matchAll(PHONE_IN_TEXT)) {
|
|
73
81
|
const raw = match[0];
|
|
74
82
|
if (!raw) continue;
|
|
@@ -81,24 +89,26 @@ function checkConsistency(pages) {
|
|
|
81
89
|
if (year >= 1990 && year <= 2100) years.add(year);
|
|
82
90
|
}
|
|
83
91
|
}
|
|
92
|
+
const templateSets = linkSets.filter((p) => !p.truncated);
|
|
84
93
|
const counts = /* @__PURE__ */ new Map();
|
|
85
|
-
for (const { hrefs } of
|
|
94
|
+
for (const { hrefs } of templateSets) {
|
|
86
95
|
for (const href of hrefs) counts.set(href, (counts.get(href) ?? 0) + 1);
|
|
87
96
|
}
|
|
88
|
-
const threshold = Math.ceil(
|
|
97
|
+
const threshold = Math.ceil(templateSets.length * 0.6);
|
|
89
98
|
const sharedNav = new Set(
|
|
90
99
|
[...counts.entries()].filter(([, n]) => n >= threshold).map(([href]) => href)
|
|
91
100
|
);
|
|
92
|
-
const canJudgeTemplate =
|
|
101
|
+
const canJudgeTemplate = templateSets.length >= 3 && sharedNav.size > 0;
|
|
93
102
|
const sortedYears = [...years].sort((a, b) => a - b);
|
|
94
103
|
return {
|
|
95
104
|
phones: [...phones.values()],
|
|
96
105
|
emails: [...emails.values()],
|
|
97
106
|
copyrightYears: sortedYears,
|
|
98
107
|
newestCopyrightYear: sortedYears.at(-1) ?? null,
|
|
99
|
-
pagesOffTemplate: canJudgeTemplate ?
|
|
108
|
+
pagesOffTemplate: canJudgeTemplate ? templateSets.filter((p) => ![...sharedNav].some((h) => p.hrefs.has(h))).map((p) => p.url) : [],
|
|
100
109
|
sharedNavLinks: sharedNav.size,
|
|
101
|
-
pagesExamined: linkSets.length
|
|
110
|
+
pagesExamined: linkSets.length,
|
|
111
|
+
pagesWithTruncatedAnchors: linkSets.filter((p) => p.truncated).map((p) => p.url)
|
|
102
112
|
};
|
|
103
113
|
}
|
|
104
114
|
|
|
@@ -734,7 +744,7 @@ function ownHost(url) {
|
|
|
734
744
|
return null;
|
|
735
745
|
}
|
|
736
746
|
}
|
|
737
|
-
function analyzeAnswerSpace(answers, prospectUrl) {
|
|
747
|
+
function analyzeAnswerSpace(answers, prospectUrl, categoryAttempted) {
|
|
738
748
|
const category = answers.filter((a) => a.kind === "category");
|
|
739
749
|
const host = ownHost(prospectUrl);
|
|
740
750
|
const counts = /* @__PURE__ */ new Map();
|
|
@@ -774,7 +784,7 @@ function analyzeAnswerSpace(answers, prospectUrl) {
|
|
|
774
784
|
const own = ownIndex === -1 ? void 0 : topSources[ownIndex];
|
|
775
785
|
return {
|
|
776
786
|
answersWithCitations,
|
|
777
|
-
queriesAsked:
|
|
787
|
+
queriesAsked: categoryAttempted,
|
|
778
788
|
citationsTotal,
|
|
779
789
|
distinctDomains: topSources.length,
|
|
780
790
|
topSources,
|
|
@@ -1045,7 +1055,7 @@ async function runVisibilityProbes(input, engines, opts = {}) {
|
|
|
1045
1055
|
// a pure read of citations already recorded, so computing it here keeps the
|
|
1046
1056
|
// ask loop to one job and lets the same function be re-run over a stored
|
|
1047
1057
|
// report if we ever backfill.
|
|
1048
|
-
answerSpace: analyzeAnswerSpace(answers, input.url)
|
|
1058
|
+
answerSpace: analyzeAnswerSpace(answers, input.url, categoryAttempted)
|
|
1049
1059
|
};
|
|
1050
1060
|
}
|
|
1051
1061
|
function perplexityEngine(apiKey, fetchImpl = fetch) {
|
|
@@ -1455,12 +1465,15 @@ ${a.fullAnswer}
|
|
|
1455
1465
|
function normalize(s) {
|
|
1456
1466
|
return s.replace(/\s+/g, " ").trim().toLowerCase();
|
|
1457
1467
|
}
|
|
1458
|
-
function distinctive(terms) {
|
|
1468
|
+
function distinctive(terms, claim) {
|
|
1469
|
+
const namesInClaim = new Set(
|
|
1470
|
+
scanWords(claim).filter((w) => w.capitalised && !w.opensSentence).map((w) => w.lower)
|
|
1471
|
+
);
|
|
1459
1472
|
return terms.map((t) => t.trim()).filter((t) => {
|
|
1460
1473
|
if (t.length < 5) return false;
|
|
1461
1474
|
const multiWord = /\s/.test(t);
|
|
1462
1475
|
const hasNumber = /\d/.test(t);
|
|
1463
|
-
const properNoun =
|
|
1476
|
+
const properNoun = namesInClaim.has(t.toLowerCase());
|
|
1464
1477
|
return multiWord || hasNumber || properNoun;
|
|
1465
1478
|
});
|
|
1466
1479
|
}
|
|
@@ -1477,7 +1490,7 @@ function backstopAbsent(assertions, siteText, searchTermsByClaim, siteFullyRead)
|
|
|
1477
1490
|
if (a.verdict !== "absent") return a;
|
|
1478
1491
|
const flat = siteText.replace(/\s+/g, " ");
|
|
1479
1492
|
let scattered = null;
|
|
1480
|
-
for (const term of distinctive(searchTermsByClaim.get(a.claim) ?? [])) {
|
|
1493
|
+
for (const term of distinctive(searchTermsByClaim.get(a.claim) ?? [], a.claim)) {
|
|
1481
1494
|
const found = findTerm(haystack, term);
|
|
1482
1495
|
if (found === null) continue;
|
|
1483
1496
|
if (found === "exact") {
|
|
@@ -1538,21 +1551,53 @@ var WEAK_WORDS = /* @__PURE__ */ new Set([
|
|
|
1538
1551
|
"based"
|
|
1539
1552
|
]);
|
|
1540
1553
|
function quoteSupportsClaim(claim, quote) {
|
|
1541
|
-
const
|
|
1554
|
+
const tokens = (t) => {
|
|
1542
1555
|
const out = /* @__PURE__ */ new Set();
|
|
1543
|
-
|
|
1544
|
-
|
|
1545
|
-
|
|
1546
|
-
if (
|
|
1547
|
-
|
|
1548
|
-
|
|
1556
|
+
const names = /* @__PURE__ */ new Set();
|
|
1557
|
+
const run = [];
|
|
1558
|
+
const flushRun = () => {
|
|
1559
|
+
if (run.length > 0) names.add(run.join(" "));
|
|
1560
|
+
run.length = 0;
|
|
1561
|
+
};
|
|
1562
|
+
for (const w of scanWords(t)) {
|
|
1563
|
+
if (WEAK_WORDS.has(w.lower)) {
|
|
1564
|
+
flushRun();
|
|
1565
|
+
continue;
|
|
1566
|
+
}
|
|
1567
|
+
const properNoun = w.capitalised && !w.opensSentence && w.raw.length >= 2;
|
|
1568
|
+
if (properNoun) run.push(w.lower);
|
|
1569
|
+
else flushRun();
|
|
1570
|
+
if (properNoun || w.lower.length >= 4) out.add(w.lower);
|
|
1549
1571
|
}
|
|
1550
|
-
|
|
1572
|
+
flushRun();
|
|
1573
|
+
return { words: out, names };
|
|
1551
1574
|
};
|
|
1552
|
-
const
|
|
1575
|
+
const c = tokens(claim);
|
|
1576
|
+
const q = tokens(quote);
|
|
1553
1577
|
let shared = 0;
|
|
1554
|
-
for (const w of words
|
|
1555
|
-
|
|
1578
|
+
for (const w of c.words) if (q.words.has(w)) shared += 1;
|
|
1579
|
+
if (shared >= 2) return true;
|
|
1580
|
+
for (const n of c.names) if (q.names.has(n)) return true;
|
|
1581
|
+
return false;
|
|
1582
|
+
}
|
|
1583
|
+
function scanWords(text) {
|
|
1584
|
+
const out = [];
|
|
1585
|
+
let opensSentence = true;
|
|
1586
|
+
let index = 0;
|
|
1587
|
+
for (const m of text.matchAll(/[A-Za-z0-9]+/g)) {
|
|
1588
|
+
const raw = m[0];
|
|
1589
|
+
const gap = text.slice(index, m.index);
|
|
1590
|
+
if (out.length > 0 && /[.!?\n\r]/.test(gap)) opensSentence = true;
|
|
1591
|
+
index = m.index + raw.length;
|
|
1592
|
+
out.push({
|
|
1593
|
+
raw,
|
|
1594
|
+
lower: raw.toLowerCase(),
|
|
1595
|
+
capitalised: /^[A-Z]/.test(raw),
|
|
1596
|
+
opensSentence
|
|
1597
|
+
});
|
|
1598
|
+
opensSentence = false;
|
|
1599
|
+
}
|
|
1600
|
+
return out;
|
|
1556
1601
|
}
|
|
1557
1602
|
function verifyQuotes(raw, answerText, siteText, answerOf, prospectDomain, searchTermsByClaim = /* @__PURE__ */ new Map()) {
|
|
1558
1603
|
const answers = normalize(answerText);
|
|
@@ -1564,7 +1609,7 @@ function verifyQuotes(raw, answerText, siteText, answerOf, prospectDomain, searc
|
|
|
1564
1609
|
let verdict = a.verdict;
|
|
1565
1610
|
let siteQuote = a.siteQuote;
|
|
1566
1611
|
if (a.verdict === "contradicted") {
|
|
1567
|
-
for (const term of distinctive(searchTermsByClaim.get(a.claim) ?? [])) {
|
|
1612
|
+
for (const term of distinctive(searchTermsByClaim.get(a.claim) ?? [], a.claim)) {
|
|
1568
1613
|
if (findTerm(site, term) !== "exact") continue;
|
|
1569
1614
|
const at = site.indexOf(normalize(term));
|
|
1570
1615
|
verdict = "confirmed";
|
|
@@ -1970,7 +2015,7 @@ function claudeCodeEngine(run = defaultClaudeCodeRun) {
|
|
|
1970
2015
|
function defaultLighthouseDeps() {
|
|
1971
2016
|
return {
|
|
1972
2017
|
async audit(site) {
|
|
1973
|
-
const { lighthouseAudit } = await import("./lighthouse-
|
|
2018
|
+
const { lighthouseAudit } = await import("./lighthouse-RFMFREEX.js");
|
|
1974
2019
|
return lighthouseAudit({ site });
|
|
1975
2020
|
}
|
|
1976
2021
|
};
|
|
@@ -2442,7 +2487,12 @@ async function checkBasics(crawl, deps) {
|
|
|
2442
2487
|
// Only meaningful on an https site, and only over the images the extract
|
|
2443
2488
|
// records — stylesheets and scripts are not captured, so the report must
|
|
2444
2489
|
// not claim to have checked them.
|
|
2445
|
-
|
|
2490
|
+
//
|
|
2491
|
+
// `imageSrcsMeasured`, not `pages.length > 0`: the loop above reads
|
|
2492
|
+
// `extract.imageSrcs ?? []`, and that field is absent on every report
|
|
2493
|
+
// stored before it existed. Counting those as measured published "we
|
|
2494
|
+
// checked and found none" from a measurement never taken.
|
|
2495
|
+
measured: isHttps && usable.imageSrcsMeasured,
|
|
2446
2496
|
imageUrls: [...insecureImages].slice(0, 12),
|
|
2447
2497
|
imagesSeen
|
|
2448
2498
|
},
|
|
@@ -3014,4 +3064,4 @@ export {
|
|
|
3014
3064
|
mergeFixes,
|
|
3015
3065
|
runProspectAudit
|
|
3016
3066
|
};
|
|
3017
|
-
//# sourceMappingURL=chunk-
|
|
3067
|
+
//# sourceMappingURL=chunk-L5F3WYIY.js.map
|