@canonry/canonry 7.70.0 → 7.72.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.
Files changed (134) hide show
  1. package/README.md +0 -5
  2. package/assets/agent-workspace/skills/canonry/references/canonry-cli.md +2 -1
  3. package/assets/assets/{AgentSetupPage-BSHWZvRa.js → AgentSetupPage-kkWYCvUB.js} +1 -1
  4. package/assets/assets/{AuditHistoryPanel-CkOJ_9_W.js → AuditHistoryPanel-BS-iFyHX.js} +1 -1
  5. package/assets/assets/{BacklinksPage-DrWQ2idL.js → BacklinksPage-BW2bEGF4.js} +1 -1
  6. package/assets/assets/{HistoryPage-XQL_fdA9.js → HistoryPage-Dh6o2iVd.js} +1 -1
  7. package/assets/assets/{MeasurementPropertyPage-Z7HN9XvJ.js → MeasurementPropertyPage-BsUyf7NF.js} +1 -1
  8. package/assets/assets/ProjectPage-CYBZBlk3.js +9 -0
  9. package/assets/assets/{RunsPage-DDlvUciW.js → RunsPage-D27pEHr4.js} +1 -1
  10. package/assets/assets/{SettingsPage-CajGcfAQ.js → SettingsPage-CkI60Uw0.js} +1 -1
  11. package/assets/assets/SiteHealthSection-BKHeLIQL.js +2 -0
  12. package/assets/assets/{ToneBadge-enK5ryht.js → ToneBadge-CmvL5mFG.js} +1 -1
  13. package/assets/assets/{TrafficPage-BlRi6C8Y.js → TrafficPage-x01Zc1a-.js} +1 -1
  14. package/assets/assets/{TrafficSourceDetailPage-DiUYQhDR.js → TrafficSourceDetailPage-DE-NyNGz.js} +1 -1
  15. package/assets/assets/{account-context-gUhEyKww.js → account-context-BwV6ox8O.js} +1 -1
  16. package/assets/assets/{card-BPDsfFv5.js → card-DhkoBNyY.js} +1 -1
  17. package/assets/assets/{extract-error-message-YbSa8SSn.js → extract-error-message-dNDtiSBo.js} +1 -1
  18. package/assets/assets/{format-helpers-B-WHGMGn.js → format-helpers-Bt4tx-f3.js} +1 -1
  19. package/assets/assets/{index-CigLVn5A.js → index-DtKWmlCj.js} +19 -19
  20. package/assets/assets/{index-CONZUwQB.css → index-Yn3nIj4B.css} +1 -1
  21. package/assets/assets/{query-client-DScmA_aM.js → query-client-D-zMw63p.js} +1 -1
  22. package/assets/assets/react-query-EdiRRB2q.js +1 -0
  23. package/assets/assets/{react-sigma_core.esm.min-CtveVGNY.js → react-sigma_core.esm.min-CmaI5ZWC.js} +1 -1
  24. package/assets/assets/{service--FVsrK0Z.js → service-C_Ai7oQC.js} +1 -1
  25. package/assets/index.html +8 -8
  26. package/dist/{ads-UTME46NF.js → ads-FFUUMS4J.js} +3 -3
  27. package/dist/{agent-PYDTNLR4.js → agent-LCD2VG7C.js} +7 -7
  28. package/dist/{agent-ask-NA4QFFM6.js → agent-ask-OBHTCYFR.js} +3 -3
  29. package/dist/{agent-conversations-3S56EX4U.js → agent-conversations-VMZ4NFIX.js} +3 -3
  30. package/dist/{agent-memory-D2RT5TVJ.js → agent-memory-UPFJFNWC.js} +3 -3
  31. package/dist/{agent-providers-5C2DRUR3.js → agent-providers-4GOWLBZK.js} +3 -3
  32. package/dist/{agent-transcript-SY5BZPO3.js → agent-transcript-RGXIVZUP.js} +3 -3
  33. package/dist/{analytics-GUENANBB.js → analytics-FBK4XV5P.js} +3 -3
  34. package/dist/{apply-R5K6RGEH.js → apply-Y2DVE3YB.js} +3 -3
  35. package/dist/{backfill-B2EXGQCW.js → backfill-ENGKBFKH.js} +9 -9
  36. package/dist/{backlinks-X55GUIQL.js → backlinks-YWHFC7DZ.js} +3 -3
  37. package/dist/{bing-5NTEC247.js → bing-7BP3DWPK.js} +3 -3
  38. package/dist/{bootstrap-UDEEVI4Z.js → bootstrap-Z7QSKVPL.js} +10 -10
  39. package/dist/{cdp-WWVZ6IBS.js → cdp-OL6RENO3.js} +7 -7
  40. package/dist/{chunk-HZ55UIKM.js → chunk-2PC54WLE.js} +4 -4
  41. package/dist/{chunk-ULUKHNE4.js → chunk-3AG3LPZX.js} +1 -1
  42. package/dist/{chunk-3LTLLHCD.js → chunk-4LTL5RNY.js} +4 -4
  43. package/dist/{chunk-3ZF3T3OG.js → chunk-6MYHGP46.js} +1 -1
  44. package/dist/{chunk-BRT5GE3Z.js → chunk-7OJQWLDI.js} +5 -5
  45. package/dist/{chunk-BGTJTKOJ.js → chunk-ATT3ZCSS.js} +3 -2
  46. package/dist/{chunk-KDV5NQZH.js → chunk-BADJCT6U.js} +1 -1
  47. package/dist/{chunk-QBR7BWO6.js → chunk-BKIFKB7E.js} +8 -8
  48. package/dist/{chunk-RPYSCFFA.js → chunk-BZZDFIY2.js} +1 -1
  49. package/dist/{chunk-R7RTWOOV.js → chunk-DRGCVTYH.js} +1 -1
  50. package/dist/{chunk-QNSMMQJY.js → chunk-GA2EHZTI.js} +7 -5
  51. package/dist/{chunk-MBNXKKOD.js → chunk-H4HNXCDF.js} +2 -2
  52. package/dist/{chunk-DW3KF33I.js → chunk-H6IQ4YCJ.js} +4 -4
  53. package/dist/{chunk-PHHQVV3G.js → chunk-IV6VZ63E.js} +3 -3
  54. package/dist/{chunk-7W4KNDAW.js → chunk-IZMT4WLZ.js} +2 -2
  55. package/dist/{chunk-CSDDKEL6.js → chunk-J523Y7X2.js} +1 -1
  56. package/dist/{chunk-6RI7JFFI.js → chunk-JE5QURTR.js} +1 -1
  57. package/dist/{chunk-CNSLBHFP.js → chunk-JEBY6MS6.js} +1 -1
  58. package/dist/{chunk-EIRIZPR6.js → chunk-JO73L677.js} +6 -3
  59. package/dist/{chunk-42JQQZZQ.js → chunk-L6WMECR5.js} +5 -5
  60. package/dist/{chunk-RVEXUQHP.js → chunk-MJYO6UK2.js} +2 -2
  61. package/dist/{chunk-NHF3OGZN.js → chunk-NZZWJCKS.js} +3 -3
  62. package/dist/{chunk-XOCF2U54.js → chunk-O7WOCTBD.js} +31 -1
  63. package/dist/{chunk-JNRMODJS.js → chunk-PPM6Z7CM.js} +1 -1
  64. package/dist/{chunk-RSK7E53V.js → chunk-Q25JQANW.js} +1 -1
  65. package/dist/{chunk-PJYXLC3D.js → chunk-QDN3FL2A.js} +1 -1
  66. package/dist/{chunk-SSNKQTRX.js → chunk-TEDY3MHN.js} +3 -3
  67. package/dist/{chunk-RJSJNR76.js → chunk-TOX6HAQJ.js} +3 -3
  68. package/dist/{chunk-OQR4F7WF.js → chunk-UWBJWKDQ.js} +2 -2
  69. package/dist/{chunk-3QHKN3JY.js → chunk-VH2KHJGT.js} +65 -33
  70. package/dist/{chunk-JGO7LGVN.js → chunk-VJFQNFOR.js} +36 -10
  71. package/dist/{chunk-SFMCFMJR.js → chunk-XR6ZVMYK.js} +1 -1
  72. package/dist/{chunk-6JGQT4OH.js → chunk-YXAKL5HM.js} +45 -2
  73. package/dist/{chunk-WOETP6NH.js → chunk-ZG4KG53J.js} +346 -336
  74. package/dist/{citations-ILU2CNT2.js → citations-RVSC67GE.js} +3 -3
  75. package/dist/{cli-catalog-ZBTUYNJA.js → cli-catalog-NEZE5QU5.js} +3 -3
  76. package/dist/{cli-commands-672L7BFD.js → cli-commands-5YNRJIN6.js} +7 -7
  77. package/dist/cli.js +13 -13
  78. package/dist/{competitor-NXSL3AWD.js → competitor-BX3M3OYS.js} +3 -3
  79. package/dist/{content-TGWYXNBI.js → content-PKJMVMHJ.js} +3 -3
  80. package/dist/{dashboard-IDCQTIYG.js → dashboard-FI5KKIP4.js} +6 -6
  81. package/dist/{demo-6X6IDMPT.js → demo-DQSDWOTF.js} +1 -1
  82. package/dist/{demo-server-HKJWIYPQ.js → demo-server-32RKOBFE.js} +11 -11
  83. package/dist/{discover-NW7NKL2Z.js → discover-JDP44ZHX.js} +3 -3
  84. package/dist/{discover-eval-2BVYL62I.js → discover-eval-6ORCVYYR.js} +3 -3
  85. package/dist/{doctor-6I3LPYM7.js → doctor-TVZRMBSS.js} +3 -3
  86. package/dist/{evidence-ZTAMPBEP.js → evidence-FNIAFBBG.js} +3 -3
  87. package/dist/{export-cmd-4CXUQVYT.js → export-cmd-HQNF2SSD.js} +3 -3
  88. package/dist/{ga-2YXMDGHQ.js → ga-PIO5OXMK.js} +3 -3
  89. package/dist/{gbp-LTPPWTUR.js → gbp-3R5FME43.js} +3 -3
  90. package/dist/{google-KTUJ4D3T.js → google-BYZREX2O.js} +4 -4
  91. package/dist/{google-marketing-FAKTAI5S.js → google-marketing-SPQ2GW6X.js} +1 -1
  92. package/dist/{health-cmd-C75E3NPQ.js → health-cmd-HH5RYMSV.js} +3 -3
  93. package/dist/{history-HE734BPT.js → history-Q35NLLMJ.js} +3 -3
  94. package/dist/index.d.ts +101 -65
  95. package/dist/index.js +24 -24
  96. package/dist/{init-M73CSTWU.js → init-O6PEZ2RT.js} +11 -11
  97. package/dist/{insights-4GUVXY2V.js → insights-SH73B4PD.js} +3 -3
  98. package/dist/intelligence-service-V2VS43H4.js +15 -0
  99. package/dist/{journeys-BZCKKFG7.js → journeys-SIV7HPW7.js} +3 -3
  100. package/dist/{keys-CMN3FUDW.js → keys-O656YWSW.js} +3 -3
  101. package/dist/{keyword-QUM65R7C.js → keyword-FZ2N4EW7.js} +3 -3
  102. package/dist/{logs-HH7EP7YK.js → logs-2NPN7HBI.js} +3 -3
  103. package/dist/{mcp-76T6WX4K.js → mcp-RHQY3DV6.js} +2 -2
  104. package/dist/mcp.js +9 -9
  105. package/dist/{measurement-plan-2D2KQLTW.js → measurement-plan-JQKVSJRL.js} +5 -5
  106. package/dist/{notify-VP5YYBJO.js → notify-VTAYBHC6.js} +3 -3
  107. package/dist/{organic-evidence-EAUZJVET.js → organic-evidence-HPXXEPOW.js} +3 -3
  108. package/dist/{overview-MCX3OHXK.js → overview-FSBNDYZJ.js} +4 -4
  109. package/dist/{project-HMELPKXT.js → project-MAPPXURS.js} +3 -3
  110. package/dist/{query-J7UTKCY5.js → query-R6DLPIPJ.js} +3 -3
  111. package/dist/{research-O4FYADRL.js → research-FXKOEUQB.js} +3 -3
  112. package/dist/{results-export-4JHIHSWW.js → results-export-X2PUM63S.js} +3 -3
  113. package/dist/{run-YJ3Y7FIE.js → run-6ENTG4IO.js} +4 -4
  114. package/dist/{schedule-6SXEB245.js → schedule-DMMVRT7P.js} +3 -3
  115. package/dist/{search-MVL346VH.js → search-FHI6APT7.js} +3 -3
  116. package/dist/{serve-GSPGAHMD.js → serve-KS6ABZHU.js} +25 -25
  117. package/dist/{session-KFFTQBJU.js → session-Q623G5DT.js} +12 -12
  118. package/dist/{settings-UKVP6TDD.js → settings-FMB4QED4.js} +3 -3
  119. package/dist/{skills-DF336KFJ.js → skills-HBIMHSOI.js} +2 -2
  120. package/dist/{snapshot-YKWGIRTM.js → snapshot-RBA2EL7R.js} +3 -3
  121. package/dist/{src-WDWTA7ON.js → src-BXXGJOQB.js} +2 -2
  122. package/dist/{status-4PDQOFYS.js → status-ATFDFAVG.js} +4 -4
  123. package/dist/{technical-aeo-XJRWNW24.js → technical-aeo-JWQTGCTB.js} +9 -5
  124. package/dist/{telemetry-TXB7NGPP.js → telemetry-6QFGJL2I.js} +4 -4
  125. package/dist/{tools-5DBHZB4K.js → tools-GNTPFDAF.js} +11 -11
  126. package/dist/{traffic-AP22ENAC.js → traffic-5R7M4CK5.js} +5 -5
  127. package/dist/{users-44XJB4ZN.js → users-24TIUYJY.js} +3 -3
  128. package/dist/{visibility-stats-5DMILJO6.js → visibility-stats-YLQPPBJJ.js} +3 -3
  129. package/dist/{wordpress-P6J44TMN.js → wordpress-7VDPHMUZ.js} +3 -3
  130. package/package.json +2 -2
  131. package/assets/assets/ProjectPage-DCOhyc0W.js +0 -9
  132. package/assets/assets/SiteHealthSection-Ch56JPKl.js +0 -2
  133. package/assets/assets/react-query-gGXPkSlb.js +0 -1
  134. package/dist/intelligence-service-PAMFRLPE.js +0 -15
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  createApiClient
3
- } from "./chunk-BGTJTKOJ.js";
3
+ } from "./chunk-ATT3ZCSS.js";
4
4
  import {
5
5
  emitJsonl
6
6
  } from "./chunk-Z7IUAJOF.js";
@@ -19,7 +19,7 @@ import {
19
19
  formatMicros,
20
20
  formatRunErrorOneLine,
21
21
  resolveProviderInput
22
- } from "./chunk-6JGQT4OH.js";
22
+ } from "./chunk-YXAKL5HM.js";
23
23
 
24
24
  // src/commands/run.ts
25
25
  function getClient() {
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  answerServiceAdapters,
3
3
  answerServiceDescriptors
4
- } from "./chunk-SFMCFMJR.js";
4
+ } from "./chunk-XR6ZVMYK.js";
5
5
  import {
6
6
  AeroLlmUsageFeatures,
7
7
  aeroTurnStatus,
@@ -27,14 +27,14 @@ import {
27
27
  resolveConfiguredAgentProvider,
28
28
  resolveSessionProviderAndModel,
29
29
  setAeroSystemPrompt
30
- } from "./chunk-BRT5GE3Z.js";
30
+ } from "./chunk-7OJQWLDI.js";
31
31
  import {
32
32
  AeroToolProfiles,
33
33
  AeroToolScopes,
34
34
  buildAeroStateTools,
35
35
  isAeroToolProfile,
36
36
  truncateToolResult
37
- } from "./chunk-DW3KF33I.js";
37
+ } from "./chunk-H6IQ4YCJ.js";
38
38
  import {
39
39
  getGoogleAuthConfig,
40
40
  getGoogleConnection,
@@ -53,7 +53,7 @@ import {
53
53
  removeCloudflareTrafficConnection,
54
54
  removeCloudflareTrafficConnectionBySourceId,
55
55
  upsertCloudflareTrafficConnection
56
- } from "./chunk-RPYSCFFA.js";
56
+ } from "./chunk-BZZDFIY2.js";
57
57
  import {
58
58
  claudeAdapter,
59
59
  embedQueries,
@@ -64,7 +64,7 @@ import {
64
64
  openaiAdapter,
65
65
  openrouterAdapter,
66
66
  perplexityAdapter
67
- } from "./chunk-EIRIZPR6.js";
67
+ } from "./chunk-JO73L677.js";
68
68
  import {
69
69
  classifyUsageSurface,
70
70
  createApiUsageTelemetry,
@@ -76,7 +76,7 @@ import {
76
76
  startOutcomeTimer,
77
77
  trackFeatureCompleted,
78
78
  trackInstallState
79
- } from "./chunk-3LTLLHCD.js";
79
+ } from "./chunk-4LTL5RNY.js";
80
80
  import {
81
81
  isLoopbackBindHost
82
82
  } from "./chunk-TSENU4GG.js";
@@ -84,7 +84,7 @@ import {
84
84
  isApiProviderRegistrable,
85
85
  isCdpProviderRegistrable,
86
86
  registeredProviderNames
87
- } from "./chunk-3ZF3T3OG.js";
87
+ } from "./chunk-6MYHGP46.js";
88
88
  import {
89
89
  checkLatestVersionForServer,
90
90
  getOrCreateAnonymousId,
@@ -95,17 +95,17 @@ import {
95
95
  recordDashboardEvent,
96
96
  setTelemetryPreference,
97
97
  trackEvent
98
- } from "./chunk-RVEXUQHP.js";
98
+ } from "./chunk-MJYO6UK2.js";
99
99
  import {
100
100
  createCanonryMcpServer
101
- } from "./chunk-PHHQVV3G.js";
101
+ } from "./chunk-IV6VZ63E.js";
102
102
  import {
103
103
  CANONRY_MCP_TIERS,
104
104
  CANONRY_MCP_TOOLKIT_NAMES
105
105
  } from "./chunk-NDTU7FGL.js";
106
106
  import {
107
107
  ApiClient
108
- } from "./chunk-BGTJTKOJ.js";
108
+ } from "./chunk-ATT3ZCSS.js";
109
109
  import {
110
110
  AGENT_PROVIDERS,
111
111
  adapterSupportsBatch,
@@ -136,21 +136,21 @@ import {
136
136
  saveConfigPatch,
137
137
  sentimentInstallReadiness,
138
138
  updateSharedProviderExecutionGate
139
- } from "./chunk-6RI7JFFI.js";
139
+ } from "./chunk-JE5QURTR.js";
140
140
  import {
141
141
  getBundledSkillSnapshots
142
- } from "./chunk-JNRMODJS.js";
142
+ } from "./chunk-PPM6Z7CM.js";
143
143
  import {
144
144
  computeFactorAverages,
145
145
  deleteSiteCrawlGraphLayout,
146
146
  persistSiteCrawlGraphLayout,
147
147
  prepareSiteCrawlGraphLayout,
148
148
  recordedSharePct
149
- } from "./chunk-7W4KNDAW.js";
149
+ } from "./chunk-IZMT4WLZ.js";
150
150
  import {
151
151
  CanonryMcpToolNames,
152
152
  canonryMcpTools
153
- } from "./chunk-QNSMMQJY.js";
153
+ } from "./chunk-GA2EHZTI.js";
154
154
  import {
155
155
  PACKAGE_VERSION
156
156
  } from "./chunk-AOJU5LKX.js";
@@ -162,11 +162,11 @@ import {
162
162
  addLogListener,
163
163
  createFastifyLogger,
164
164
  createLogger
165
- } from "./chunk-42JQQZZQ.js";
165
+ } from "./chunk-L6WMECR5.js";
166
166
  import {
167
167
  computeCitedCompetitorDomains,
168
168
  determineCitationState
169
- } from "./chunk-R7RTWOOV.js";
169
+ } from "./chunk-DRGCVTYH.js";
170
170
  import {
171
171
  BingApiError,
172
172
  CC_CACHE_DIR,
@@ -286,7 +286,7 @@ import {
286
286
  webhookResponseReason,
287
287
  webhookTargetRefusalReason,
288
288
  writeAuditLog
289
- } from "./chunk-JGO7LGVN.js";
289
+ } from "./chunk-VJFQNFOR.js";
290
290
  import {
291
291
  OperationalLogStore,
292
292
  SentimentIdempotencyConflict,
@@ -372,7 +372,7 @@ import {
372
372
  siteLivenessState,
373
373
  trafficSources,
374
374
  usageCounters
375
- } from "./chunk-XOCF2U54.js";
375
+ } from "./chunk-O7WOCTBD.js";
376
376
  import {
377
377
  AGENT_MEMORY_VALUE_MAX_BYTES,
378
378
  AI_ENGINE_DOMAINS,
@@ -446,6 +446,7 @@ import {
446
446
  SITE_AUDIT_DEFAULT_PAGE_LIMIT,
447
447
  SITE_AUDIT_MAX_EDGE_LIMIT,
448
448
  SITE_AUDIT_MAX_PAGE_LIMIT,
449
+ SITE_CRAWL_URL_VERSION_AUDIT_STATE,
449
450
  STORED_ONLY_HEADER,
450
451
  SchedulableRunKinds,
451
452
  SentimentOutcomes,
@@ -606,6 +607,7 @@ import {
606
607
  serializeRunError,
607
608
  shiftIsoCalendarDate,
608
609
  siteAuditRequestIdentity,
610
+ siteCrawlUrlVersionOf,
609
611
  splitList,
610
612
  startOfDayHourInTimeZone,
611
613
  statusClassOf,
@@ -622,7 +624,7 @@ import {
622
624
  winnabilityClassLabel,
623
625
  withRetry,
624
626
  withSkippedProviders
625
- } from "./chunk-6JGQT4OH.js";
627
+ } from "./chunk-YXAKL5HM.js";
626
628
 
627
629
  // src/google-marketing-runtime.ts
628
630
  import crypto2 from "crypto";
@@ -5805,7 +5807,7 @@ function nonBlank(value) {
5805
5807
  return trimmed ? trimmed : void 0;
5806
5808
  }
5807
5809
  function resolveBuildCommit(env = process.env) {
5808
- const embedded = true ? "248bb6e43737a9fdd7b9fc5f05a1e150c58843a4" : void 0;
5810
+ const embedded = true ? "5316fa88fb0c94357b949d9442ad4ce1b8307880" : void 0;
5809
5811
  return nonBlank(embedded) ?? nonBlank(env.CANONRY_COMMIT);
5810
5812
  }
5811
5813
  function resolveInstanceIdentity(env = process.env) {
@@ -11882,6 +11884,7 @@ var log14 = createLogger("SiteAudit");
11882
11884
  var SiteAuditCancelledError = class extends Error {
11883
11885
  name = "SiteAuditCancelledError";
11884
11886
  };
11887
+ var SITE_AUDIT_SKIP_URL_VERSIONS_AFTER = 3;
11885
11888
  var NON_PAGE_MEDIA_EXTENSIONS = /\.(?:jpe?g|png|gif|webp|avif|bmp|ico|tiff?|svg|mp4|webm|mov|avi|mp3|wav|ogg|woff2?|ttf|otf|eot)(?:$|\?)/i;
11886
11889
  var NON_PAGE_MEDIA_CONTENT_TYPE = /^(?:image|video|audio|font)\//i;
11887
11890
  function isNonPageMedia(page) {
@@ -11948,7 +11951,14 @@ function pageDiscoverySource(page) {
11948
11951
  if (page.provenance.sitemapSources.length > 0) return "sitemap";
11949
11952
  return "link";
11950
11953
  }
11954
+ function urlVersionOf(page) {
11955
+ return siteCrawlUrlVersionOf({ fetchState: page.state, url: page.requestedUrl, canonicalUrl: page.canonicalUrl });
11956
+ }
11957
+ function isScoredPage(page) {
11958
+ return page.audit != null && urlVersionOf(page) === null;
11959
+ }
11951
11960
  function pageAuditState(page) {
11961
+ if (urlVersionOf(page) !== null) return SITE_CRAWL_URL_VERSION_AUDIT_STATE;
11952
11962
  if (page.audit) return "success";
11953
11963
  if (page.state === "fetch-error") return "error";
11954
11964
  return "not-applicable";
@@ -11962,7 +11972,7 @@ function isCancelled(error, signal) {
11962
11972
  return error instanceof DOMException && error.name === "AbortError";
11963
11973
  }
11964
11974
  function isLegacyScorecardPage(page) {
11965
- return page.audit != null || page.state === "fetch-error";
11975
+ return isScoredPage(page) || page.state === "fetch-error";
11966
11976
  }
11967
11977
  function emptyCompleteCrawlError(rootUrl, finalRootUrl, pagesObserved) {
11968
11978
  if (!finalRootUrl) return new Error(`Site audit could not successfully audit any of ${pagesObserved} observed page(s).`);
@@ -12110,7 +12120,8 @@ async function executeSiteAudit(db, runId, projectId, opts = {}) {
12110
12120
  }
12111
12121
  };
12112
12122
  const persistPage = (tx, page, now) => {
12113
- const audit = page.audit;
12123
+ const versionOf = urlVersionOf(page);
12124
+ const audit = versionOf === null ? page.audit : null;
12114
12125
  const canonicalNodeKey = page.canonicalUrl ? nodeKeyByUrl.get(page.canonicalUrl) ?? null : null;
12115
12126
  const healthState = deriveSiteHealthState({
12116
12127
  fetchState: page.state,
@@ -12147,6 +12158,7 @@ async function executeSiteAudit(db, runId, projectId, opts = {}) {
12147
12158
  indexabilityState: page.indexability.state,
12148
12159
  indexabilityReasons: page.indexability.reasons,
12149
12160
  healthState,
12161
+ urlVersionOf: versionOf,
12150
12162
  auditState: pageAuditState(page),
12151
12163
  auditScore: audit?.overallScore ?? null,
12152
12164
  auditFields: audit ? crawlAuditFields(audit) : {},
@@ -12181,6 +12193,7 @@ async function executeSiteAudit(db, runId, projectId, opts = {}) {
12181
12193
  indexabilityState: page.indexability.state,
12182
12194
  indexabilityReasons: page.indexability.reasons,
12183
12195
  healthState,
12196
+ urlVersionOf: versionOf,
12184
12197
  auditState: pageAuditState(page),
12185
12198
  auditScore: audit?.overallScore ?? null,
12186
12199
  auditFields: audit ? crawlAuditFields(audit) : {},
@@ -12305,6 +12318,8 @@ async function executeSiteAudit(db, runId, projectId, opts = {}) {
12305
12318
  pagesFetched: progress.pagesFetched,
12306
12319
  pagesEligible: event.type === "summary" ? observedPages.size === 0 ? 0 : [...observedPages.values()].filter(isInventoryEligible).length : sql6`${siteCrawlAttempts.pagesEligible}`,
12307
12320
  pagesErrored: event.type === "summary" ? observedErrorCount(observedPages.values()) : sql6`${siteCrawlAttempts.pagesErrored}`,
12321
+ // Only the summary knows how many URL versions the crawl left unfetched.
12322
+ urlVersionsSkipped: event.type === "summary" ? event.summary.urlVersions?.skipped ?? 0 : sql6`${siteCrawlAttempts.urlVersionsSkipped}`,
12308
12323
  edgesDiscovered: progress.edgesObserved,
12309
12324
  updatedAt: now
12310
12325
  }).where(eq18(siteCrawlAttempts.id, attemptId)).run();
@@ -12349,12 +12364,12 @@ async function executeSiteAudit(db, runId, projectId, opts = {}) {
12349
12364
  checkDeadLinks: opts.checkDeadLinks ?? false,
12350
12365
  includeGeo: opts.includeGeo ?? false,
12351
12366
  includeAgentSkills: opts.includeAgentSkills ?? true,
12367
+ skipUrlVersionsAfter: SITE_AUDIT_SKIP_URL_VERSIONS_AFTER,
12352
12368
  signal: opts.signal,
12353
12369
  onEvent: persistEvent
12354
12370
  });
12355
12371
  const crawlSummary = report.summary;
12356
- const hasAuditedPages = crawlSummary.auditRollup.auditedPages > 0;
12357
- if (crawlSummary.complete && !hasAuditedPages) {
12372
+ if (crawlSummary.complete && crawlSummary.auditRollup.auditedPages === 0) {
12358
12373
  throw emptyCompleteCrawlError(crawlSummary.rootUrl, crawlSummary.finalRootUrl, crawlSummary.pagesObserved);
12359
12374
  }
12360
12375
  const placementRulesetVersion = crawlSummary.linkPlacementRulesetVersion ?? null;
@@ -12379,7 +12394,11 @@ async function executeSiteAudit(db, runId, projectId, opts = {}) {
12379
12394
  rootUrl: crawlSummary.finalRootUrl ?? crawlSummary.rootUrl
12380
12395
  }, { signal: opts.signal, timeoutMs: opts.graphLayoutTimeoutMs });
12381
12396
  const finishedAt = (/* @__PURE__ */ new Date()).toISOString();
12382
- const factors = computeFactorAverages([...observedPages.values()]);
12397
+ const pageObservations = [...observedPages.values()].filter((page) => urlVersionOf(page) === null);
12398
+ const scoredPages = pageObservations.filter(isScoredPage);
12399
+ const pagesAudited = scoredPages.length;
12400
+ const aggregateScore = pagesAudited > 0 ? Math.round(scoredPages.reduce((total, page) => total + page.audit.overallScore, 0) / pagesAudited) : null;
12401
+ const factors = computeFactorAverages(pageObservations);
12383
12402
  const errorCount = observedErrorCount(observedPages.values());
12384
12403
  const terminalStatus = crawlSummary.complete ? "completed" : "partial";
12385
12404
  const deadLinksChecked = opts.checkDeadLinks ? deadLinkCheckedCount(observedEdges.values(), observedPages.values()) : 0;
@@ -12387,8 +12406,8 @@ async function executeSiteAudit(db, runId, projectId, opts = {}) {
12387
12406
  const unverifiedLinks = report.deadLinks.unverified;
12388
12407
  const deadLinksFound = deadLinkFindings.length;
12389
12408
  const deadLinksUnverified = new Set(unverifiedLinks.map((finding) => finding.to)).size;
12390
- const legacyIssues = factors.map((factor) => toLegacyIssue(factor, crawlSummary.auditRollup.auditedPages)).filter((issue) => issue !== null);
12391
- const issueEvidence = buildSiteCrawlIssueEvidence(crawlSummary.siteIssues, observedPages.values());
12409
+ const legacyIssues = factors.map((factor) => toLegacyIssue(factor, pagesAudited)).filter((issue) => issue !== null);
12410
+ const issueEvidence = buildSiteCrawlIssueEvidence(crawlSummary.siteIssues, pageObservations);
12392
12411
  try {
12393
12412
  persistSiteCrawlGraphLayout(db, { projectId, runId, attemptId }, graphLayout, finishedAt);
12394
12413
  } catch (error) {
@@ -12420,16 +12439,16 @@ async function executeSiteAudit(db, runId, projectId, opts = {}) {
12420
12439
  const published = db.transaction((tx) => {
12421
12440
  const claim2 = tx.update(runs).set({ status: terminalStatus, finishedAt }).where(and14(eq18(runs.id, runId), eq18(runs.status, "running"))).run();
12422
12441
  if (claim2.changes === 0) return false;
12423
- if (hasAuditedPages) {
12442
+ if (aggregateScore !== null) {
12424
12443
  tx.insert(siteAuditSnapshots).values({
12425
12444
  id: crypto19.randomUUID(),
12426
12445
  projectId,
12427
12446
  runId,
12428
12447
  sitemapUrl: opts.sitemapUrl ?? new URL("/sitemap.xml", crawlRootUrl).href,
12429
12448
  auditedAt: crawlSummary.completedAt,
12430
- aggregateScore: crawlSummary.auditRollup.aggregateScore ?? 0,
12449
+ aggregateScore,
12431
12450
  pagesDiscovered: crawlSummary.pagesDiscovered,
12432
- pagesAudited: crawlSummary.auditRollup.auditedPages,
12451
+ pagesAudited,
12433
12452
  pagesSkipped: Math.max(0, crawlSummary.pagesDiscovered - crawlSummary.pagesObserved),
12434
12453
  pagesErrored: errorCount,
12435
12454
  factorAverages: factors,
@@ -12545,7 +12564,20 @@ async function executeSiteAudit(db, runId, projectId, opts = {}) {
12545
12564
  if (current?.status === "cancelled") throw new SiteAuditCancelledError(`Site audit cancelled before publication: ${runId}`);
12546
12565
  throw new Error(`Site audit run was no longer running before publication: ${runId}`);
12547
12566
  }
12548
- log14.info("completed", { runId, projectId, status: terminalStatus, complete: crawlSummary.complete, pages: crawlSummary.pagesObserved });
12567
+ log14.info("completed", {
12568
+ runId,
12569
+ projectId,
12570
+ status: terminalStatus,
12571
+ complete: crawlSummary.complete,
12572
+ pages: crawlSummary.pagesObserved,
12573
+ urlVersionsSkipped: crawlSummary.urlVersions?.skipped ?? 0,
12574
+ urlVersionPatterns: (crawlSummary.urlVersions?.patterns ?? []).map((pattern) => ({
12575
+ section: pattern.section,
12576
+ parameters: pattern.parameters,
12577
+ copies: pattern.copies,
12578
+ skipped: pattern.skipped
12579
+ }))
12580
+ });
12549
12581
  trackSiteAuditOutcome(db, {
12550
12582
  runId,
12551
12583
  projectId,
@@ -12558,9 +12590,9 @@ async function executeSiteAudit(db, runId, projectId, opts = {}) {
12558
12590
  termination: crawlSummary.terminationReason,
12559
12591
  pagesDiscovered: crawlSummary.pagesDiscovered,
12560
12592
  pagesFetched: crawlSummary.pagesFetched,
12561
- pagesAudited: crawlSummary.auditRollup.auditedPages,
12593
+ pagesAudited,
12562
12594
  pagesErrored: errorCount,
12563
- aggregateScore: crawlSummary.auditRollup.aggregateScore,
12595
+ aggregateScore,
12564
12596
  pageBudget: maxPages,
12565
12597
  checkDeadLinks: opts.checkDeadLinks ?? false,
12566
12598
  deadLinksFound
@@ -9,14 +9,14 @@ import {
9
9
  normalizeCloudflareWorkerEvent,
10
10
  sessionizeJourneyRequests,
11
11
  verifyRequestSignature
12
- } from "./chunk-CNSLBHFP.js";
12
+ } from "./chunk-JEBY6MS6.js";
13
13
  import {
14
14
  currentOutcomeAttribution,
15
15
  getRequestContext,
16
16
  registerRequestContext,
17
17
  requestAuditIdentity,
18
18
  sanitizeRequestContext
19
- } from "./chunk-KDV5NQZH.js";
19
+ } from "./chunk-BADJCT6U.js";
20
20
  import {
21
21
  SentimentIdempotencyConflict,
22
22
  SentimentRepository,
@@ -156,7 +156,7 @@ import {
156
156
  userSessions,
157
157
  users,
158
158
  writeNegativeReviewMaxStars
159
- } from "./chunk-XOCF2U54.js";
159
+ } from "./chunk-O7WOCTBD.js";
160
160
  import {
161
161
  ADS_ACTIVATE_SCOPE,
162
162
  ADS_ACTIVATION_ABSOLUTE_MAX_ENTITIES,
@@ -378,6 +378,7 @@ import {
378
378
  SiteAuditTrendDirections,
379
379
  SiteCrawlFetchedStates,
380
380
  SiteCrawlIndexabilityReasons,
381
+ SiteCrawlUrlVersionFilters,
381
382
  SiteHealthLinkKinds,
382
383
  SiteHealthTemplateDetections,
383
384
  TrafficEventConfidences,
@@ -1111,6 +1112,7 @@ import {
1111
1112
  siteCrawlPagesResponseSchema,
1112
1113
  siteCrawlStructureResponseSchema,
1113
1114
  siteCrawlSummarySchema,
1115
+ siteCrawlUrlVersionFilterSchema,
1114
1116
  siteHealthChangesResponseSchema,
1115
1117
  siteHealthLinkKindSchema,
1116
1118
  siteHealthPathResponseSchema,
@@ -1192,7 +1194,7 @@ import {
1192
1194
  wordpressSchemaDeployResultDtoSchema,
1193
1195
  wordpressSchemaStatusResultDtoSchema,
1194
1196
  wordpressStatusDtoSchema
1195
- } from "./chunk-6JGQT4OH.js";
1197
+ } from "./chunk-YXAKL5HM.js";
1196
1198
 
1197
1199
  // ../api-routes/src/user-session.ts
1198
1200
  import crypto2 from "crypto";
@@ -42309,13 +42311,14 @@ var routeCatalog = [
42309
42311
  { name: "indexabilityState", in: "query", description: "Filter by crawler-derived indexability state; this is not Google index coverage.", schema: stringSchema },
42310
42312
  { name: "nodeKey", in: "query", description: "Return only the page with this node key. Combined with a filter it answers whether that exact page is in the filtered set, without paging through the list.", schema: stringSchema },
42311
42313
  { name: "healthState", in: "query", description: "Filter by the derived Site Health state shared with the dashboard and agents. Unlike `indexabilityState` this folds fetch state, canonical identity, and the crawler reasons into one decision. `hidden` means the SITE told answer engines not to index the page (noindex, canonical-away, robots.txt); a non-HTML file is `resource` and a redirect is `redirect`, because neither is suppressed. Values: `eligible`, `hidden`, `resource`, `redirect`, `failed`, `unchecked`.", schema: { type: "string", enum: ["eligible", "hidden", "resource", "redirect", "failed", "unchecked"] } },
42312
- { name: "auditState", in: "query", description: "Filter by audit state.", schema: stringSchema },
42314
+ { name: "auditState", in: "query", description: "Filter by audit state. A URL version has `url-version`: it was fetched and classified but not scored.", schema: stringSchema },
42315
+ { name: "urlVersions", in: "query", description: "URL versions are parameter addresses (filters, views, cache settings) whose canonical names the same path, so the site marks them as copies of that page. The audit does not score them or count them in fixes, and `inventorySummary.urlVersions` counts them. `include` (default) keeps every crawled address, `exclude` lists pages only, as the dashboard does, and `only` lists the URL versions, each with `urlVersionOf`. Once a few addresses with the same parameter pattern prove to be copies, the crawl stops fetching that pattern: those have no rows and `inventorySummary.urlVersionsNotFetched` counts them. Scans made before URL versions were set aside have none.", schema: { type: "string", enum: ["include", "exclude", "only"] } },
42313
42316
  { name: "sort", in: "query", description: "Sort order. Defaults to `url`.", schema: { type: "string", enum: ["url", "path", "score-asc", "score-desc"] } },
42314
42317
  crawlCursorParameter,
42315
42318
  crawlLimitParameter
42316
42319
  ],
42317
42320
  responses: {
42318
- 400: errorResponse("Invalid date, conflicting runId/date, or invalid cursor identity."),
42321
+ 400: errorResponse("Invalid date, conflicting runId/date, invalid urlVersions, or invalid cursor identity."),
42319
42322
  200: jsonResponse("Crawl pages returned.", "SiteCrawlPagesResponseDto"),
42320
42323
  404: errorResponse("Project or site-audit run not found. A known run that published no crawl returns 200 with the no-crawl state instead.")
42321
42324
  }
@@ -72106,6 +72109,14 @@ function parseSiteHealthState(value) {
72106
72109
  }
72107
72110
  return allowed.data;
72108
72111
  }
72112
+ function parseUrlVersionFilter(value) {
72113
+ if (value === void 0 || value === "") return SiteCrawlUrlVersionFilters.include;
72114
+ const allowed = siteCrawlUrlVersionFilterSchema.safeParse(value);
72115
+ if (!allowed.success) {
72116
+ throw validationError(`"urlVersions" must be one of: ${siteCrawlUrlVersionFilterSchema.options.join(", ")}`);
72117
+ }
72118
+ return allowed.data;
72119
+ }
72109
72120
  function parseBoolean2(value) {
72110
72121
  if (value === true || value === "true" || value === "1") return true;
72111
72122
  if (value === false || value === "false" || value === "0") return false;
@@ -72188,7 +72199,8 @@ function mapCrawlPage(row) {
72188
72199
  linkScoreRaw: row.linkScoreRaw,
72189
72200
  linkScoreNormalized: row.linkScoreNormalized,
72190
72201
  healthState: deriveSiteHealthState(row),
72191
- healthReason: deriveSiteHealthReason(row)
72202
+ healthReason: deriveSiteHealthReason(row),
72203
+ urlVersionOf: row.urlVersionOf ?? null
72192
72204
  };
72193
72205
  }
72194
72206
  function withRecordedShare(factor) {
@@ -72559,19 +72571,28 @@ async function technicalAeoRoutes(app, opts) {
72559
72571
  };
72560
72572
  const inventorySummaryFor = (scope) => {
72561
72573
  if (!scope) return null;
72562
- const groups = crawlReasonGroups(and83(
72574
+ const inScope = and83(
72563
72575
  eq100(siteCrawlPages.projectId, scope.projectId),
72564
72576
  eq100(siteCrawlPages.runId, scope.runId),
72565
72577
  eq100(siteCrawlPages.attemptId, scope.attemptId)
72566
- ));
72578
+ );
72579
+ const groups = crawlReasonGroups(inScope);
72567
72580
  const total = groups.reduce((sum, group) => sum + group.pages, 0);
72568
72581
  const eligible = groups.reduce((sum, group) => sum + (group.inventoryEligible ? group.pages : 0), 0);
72582
+ const urlVersions = app.db.select({ value: count8() }).from(siteCrawlPages).where(and83(inScope, isNotNull10(siteCrawlPages.urlVersionOf))).get()?.value ?? 0;
72583
+ const urlVersionsNotFetched = app.db.select({ value: siteCrawlAttempts.urlVersionsSkipped }).from(siteCrawlAttempts).where(and83(
72584
+ eq100(siteCrawlAttempts.projectId, scope.projectId),
72585
+ eq100(siteCrawlAttempts.runId, scope.runId),
72586
+ eq100(siteCrawlAttempts.id, scope.attemptId)
72587
+ )).get()?.value ?? 0;
72569
72588
  return {
72570
72589
  scope: "selected-snapshot",
72571
72590
  total,
72572
72591
  eligible,
72573
72592
  excluded: total - eligible,
72574
- excludedReasons: reasonCounts(groups.filter((group) => !group.inventoryEligible))
72593
+ excludedReasons: reasonCounts(groups.filter((group) => !group.inventoryEligible)),
72594
+ urlVersions,
72595
+ urlVersionsNotFetched
72575
72596
  };
72576
72597
  };
72577
72598
  const completenessOf = (target) => ({
@@ -73739,6 +73760,9 @@ async function technicalAeoRoutes(app, opts) {
73739
73760
  if (request.query.fetchState) filters.push(eq100(siteCrawlPages.fetchState, request.query.fetchState));
73740
73761
  if (request.query.indexabilityState) filters.push(eq100(siteCrawlPages.indexabilityState, request.query.indexabilityState));
73741
73762
  if (request.query.auditState) filters.push(eq100(siteCrawlPages.auditState, request.query.auditState));
73763
+ const urlVersions = parseUrlVersionFilter(request.query.urlVersions);
73764
+ if (urlVersions === SiteCrawlUrlVersionFilters.exclude) filters.push(isNull17(siteCrawlPages.urlVersionOf));
73765
+ if (urlVersions === SiteCrawlUrlVersionFilters.only) filters.push(isNotNull10(siteCrawlPages.urlVersionOf));
73742
73766
  const healthState = parseSiteHealthState(request.query.healthState);
73743
73767
  const limit = parseBoundedLimit(request.query.limit, 100, 200);
73744
73768
  const sort = ["score-desc", "score-asc", "path"].includes(request.query.sort ?? "") ? request.query.sort : "url";
@@ -73752,6 +73776,8 @@ async function technicalAeoRoutes(app, opts) {
73752
73776
  fetchState: request.query.fetchState || null,
73753
73777
  indexabilityState: request.query.indexabilityState || null,
73754
73778
  auditState: request.query.auditState || null,
73779
+ // Absent for the default, so a cursor issued before this filter existed still matches.
73780
+ ...urlVersions === SiteCrawlUrlVersionFilters.include ? {} : { urlVersions },
73755
73781
  healthState,
73756
73782
  sort
73757
73783
  })).digest("base64url");
@@ -28,7 +28,7 @@ import {
28
28
  unknownUsageObservation,
29
29
  usdToMicros,
30
30
  withRetry
31
- } from "./chunk-6JGQT4OH.js";
31
+ } from "./chunk-YXAKL5HM.js";
32
32
 
33
33
  // ../provider-answer-services/src/core/http.ts
34
34
  var MAX_RESPONSE_BYTES = 8 * 1024 * 1024;
@@ -7905,7 +7905,21 @@ var siteCrawlInventorySummarySchema = z20.object({
7905
7905
  eligible: z20.number().int().nonnegative(),
7906
7906
  excluded: z20.number().int().nonnegative(),
7907
7907
  /** Disjoint primary reasons: their page counts sum to excluded. */
7908
- excludedReasons: z20.array(siteCrawlHealthReasonCountSchema).max(siteHealthReasonSchema.options.length)
7908
+ excludedReasons: z20.array(siteCrawlHealthReasonCountSchema).max(siteHealthReasonSchema.options.length),
7909
+ /**
7910
+ * URL versions the audit set aside (see `siteCrawlUrlVersionOf`): not scored
7911
+ * and not counted in fixes. A subset of `excluded`; 0 for a scan made before
7912
+ * the audit set them aside, which scored every address.
7913
+ */
7914
+ urlVersions: z20.number().int().nonnegative().default(0),
7915
+ /**
7916
+ * URL versions the crawl did not fetch at all: once a few addresses with
7917
+ * the same parameter pattern proved to be copies, it skipped the rest. They
7918
+ * have no page rows, so they are outside `total` and `urlVersions`; the URL
7919
+ * versions a scan found are `urlVersions + urlVersionsNotFetched`. 0 for a
7920
+ * scan that fetched every address.
7921
+ */
7922
+ urlVersionsNotFetched: z20.number().int().nonnegative().default(0)
7909
7923
  });
7910
7924
  var siteCrawlAvailableScanDatesSchema = z20.object({
7911
7925
  /** Most recent distinct visible crawl dates, newest first. Fewer rows than totalDates means the list is bounded. */
@@ -8082,6 +8096,24 @@ function deriveSiteHealthState(input) {
8082
8096
  return "unchecked";
8083
8097
  }
8084
8098
  }
8099
+ var siteCrawlUrlVersionFilterSchema = z20.enum(["include", "exclude", "only"]);
8100
+ var SiteCrawlUrlVersionFilters = siteCrawlUrlVersionFilterSchema.enum;
8101
+ var SITE_CRAWL_URL_VERSION_AUDIT_STATE = "url-version";
8102
+ function siteCrawlUrlVersionOf(input) {
8103
+ if (input.fetchState !== SiteCrawlFetchStates.html || !input.canonicalUrl) return null;
8104
+ let own;
8105
+ let canonical;
8106
+ try {
8107
+ own = new URL(input.url);
8108
+ canonical = new URL(input.canonicalUrl);
8109
+ } catch {
8110
+ return null;
8111
+ }
8112
+ if (own.search === "") return null;
8113
+ if (hostOf(own.href) !== hostOf(canonical.href) || own.pathname !== canonical.pathname) return null;
8114
+ if (own.search === canonical.search) return null;
8115
+ return canonical.href;
8116
+ }
8085
8117
  var TEMPLATE_LINK_RATIO_THRESHOLD = 0.7;
8086
8118
  var TEMPLATE_LINK_MIN_FETCHED_PAGES = 15;
8087
8119
  var siteCrawlLinkPlacementSchema = z20.enum(["navigation", "content", "unknown"]);
@@ -8251,7 +8283,14 @@ var siteCrawlPageSchema = z20.object({
8251
8283
  linkScoreNormalized: percent().nullable(),
8252
8284
  healthState: siteHealthStateSchema,
8253
8285
  /** Concrete fetch/indexability reason; unknown never implies a canonical points elsewhere. */
8254
- healthReason: siteHealthReasonSchema.optional()
8286
+ healthReason: siteHealthReasonSchema.optional(),
8287
+ /**
8288
+ * The page this address is a URL version of (its canonical), or null for a
8289
+ * page. A URL version is not scored: its `auditState` is `url-version` and
8290
+ * its `auditScore` null. Always null in a scan made before the audit set URL
8291
+ * versions aside.
8292
+ */
8293
+ urlVersionOf: z20.string().nullable().default(null)
8255
8294
  });
8256
8295
  var siteCrawlAuditFindingSchema = z20.object({
8257
8296
  type: z20.enum(["found", "missing", "info", "timeout", "unreachable"]),
@@ -26709,6 +26748,10 @@ export {
26709
26748
  SiteCrawlIndexabilityReasons,
26710
26749
  deriveSiteHealthReason,
26711
26750
  deriveSiteHealthState,
26751
+ siteCrawlUrlVersionFilterSchema,
26752
+ SiteCrawlUrlVersionFilters,
26753
+ SITE_CRAWL_URL_VERSION_AUDIT_STATE,
26754
+ siteCrawlUrlVersionOf,
26712
26755
  TEMPLATE_LINK_RATIO_THRESHOLD,
26713
26756
  SiteHealthLinkClassificationSources,
26714
26757
  siteHealthTemplateDetectionSchema,