@canonry/canonry 7.58.4 → 7.59.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 (131) hide show
  1. package/assets/agent-workspace/skills/canonry/references/canonry-cli.md +30 -0
  2. package/assets/agent-workspace/skills/canonry/references/server-side-traffic.md +52 -13
  3. package/assets/assets/{AgentSetupPage-CoD9a386.js → AgentSetupPage-DH2Mi2Q7.js} +1 -1
  4. package/assets/assets/{AuditHistoryPanel-DSUKF9GC.js → AuditHistoryPanel-DVIQR5y5.js} +1 -1
  5. package/assets/assets/{BacklinksPage-DIZy0NkW.js → BacklinksPage-DFFeaSbH.js} +1 -1
  6. package/assets/assets/{HistoryPage-B2Xtxu5L.js → HistoryPage-BxDhO9rm.js} +1 -1
  7. package/assets/assets/{MeasurementPropertyPage-BZmvjMiS.js → MeasurementPropertyPage-B0AkDYxY.js} +1 -1
  8. package/assets/assets/{ProjectPage-DMIoYBCF.js → ProjectPage-6_HOcytx.js} +1 -1
  9. package/assets/assets/{RunsPage-DtvesLu2.js → RunsPage-BUK5EqC6.js} +1 -1
  10. package/assets/assets/{SettingsPage-BjE3d5Ae.js → SettingsPage-CuBUZ4TN.js} +1 -1
  11. package/assets/assets/{SiteHealthSection-D6RLbM2o.js → SiteHealthSection-CoyiSleA.js} +2 -2
  12. package/assets/assets/ToneBadge-Du4fOtJa.js +60 -0
  13. package/assets/assets/{TrafficPage-CHZlfMgd.js → TrafficPage-BE9Ay-x-.js} +1 -1
  14. package/assets/assets/{TrafficSourceDetailPage-Dp7AYvRP.js → TrafficSourceDetailPage-kW0DFcwB.js} +1 -1
  15. package/assets/assets/{account-context-DHWaWJSr.js → account-context-IN6VE8PV.js} +1 -1
  16. package/assets/assets/{card-im88-x1b.js → card-DiBSxANp.js} +1 -1
  17. package/assets/assets/{extract-error-message-Bq8oNvfF.js → extract-error-message-_H20efSf.js} +1 -1
  18. package/assets/assets/{format-helpers-DOEct2q8.js → format-helpers-DKjsmbxo.js} +1 -1
  19. package/assets/assets/{index-CgAMnZFS.js → index-B1kVq-wC.js} +4 -4
  20. package/assets/assets/{query-client-BN_-qp71.js → query-client-BXS2w17E.js} +1 -1
  21. package/assets/assets/{react-query-P6OZ-MPl.js → react-query-B8oOFCyW.js} +1 -1
  22. package/assets/assets/{react-sigma_core.esm.min-TGwpCHs4.js → react-sigma_core.esm.min-Bf_kjp11.js} +1 -1
  23. package/assets/assets/{service-CUJkePNp.js → service-D9noo7pB.js} +1 -1
  24. package/assets/index.html +7 -7
  25. package/dist/{ads-BMBXQB67.js → ads-6NAIIZGO.js} +3 -3
  26. package/dist/{agent-S6CU36RL.js → agent-LISFS4WR.js} +7 -7
  27. package/dist/{agent-ask-XG7WQBX6.js → agent-ask-JJM34LMD.js} +3 -3
  28. package/dist/{agent-conversations-C4QBZAPC.js → agent-conversations-4JNBIBVR.js} +3 -3
  29. package/dist/{agent-memory-I7UJ7MKH.js → agent-memory-I2M7TIWO.js} +3 -3
  30. package/dist/{agent-providers-YHRIYJDT.js → agent-providers-3ZX3RETW.js} +3 -3
  31. package/dist/{agent-transcript-2WICUOEW.js → agent-transcript-OYK4O5XV.js} +3 -3
  32. package/dist/{analytics-Y5AGSYWD.js → analytics-7HW2FSST.js} +3 -3
  33. package/dist/{apply-DLVLMU3O.js → apply-S2OC6S65.js} +3 -3
  34. package/dist/{backfill-JAHDHVXJ.js → backfill-EUHHN4VT.js} +9 -9
  35. package/dist/{backlinks-TEZTPNZ5.js → backlinks-AY5EMVN4.js} +3 -3
  36. package/dist/{bing-IIA5HLND.js → bing-KJW2LYAT.js} +3 -3
  37. package/dist/{bootstrap-AKGA3BJI.js → bootstrap-3R4AMSY4.js} +10 -10
  38. package/dist/{cdp-WWOFWFYU.js → cdp-URC66DX5.js} +7 -7
  39. package/dist/{chunk-ZYL3LCDZ.js → chunk-3WRDJJOY.js} +1 -1
  40. package/dist/{chunk-NMLVLFF7.js → chunk-B4N5L6NF.js} +5 -5
  41. package/dist/{chunk-N2HCXIQ3.js → chunk-EED2QEE7.js} +1 -1
  42. package/dist/{chunk-IFVTHGXG.js → chunk-EJZ4TQQR.js} +2 -2
  43. package/dist/{chunk-TVANRUBO.js → chunk-FA7RDZ43.js} +8 -1
  44. package/dist/{chunk-CFGA6OAK.js → chunk-GS6IH7CI.js} +404 -330
  45. package/dist/{chunk-6A6BD5KS.js → chunk-HKLI6ZFP.js} +23 -20
  46. package/dist/{chunk-Y7NX6EIK.js → chunk-HUO3YPKB.js} +2650 -2405
  47. package/dist/{chunk-BP5OKJIC.js → chunk-JLDTGMVQ.js} +2 -2
  48. package/dist/{chunk-3U7LL3JM.js → chunk-KCO3PGDZ.js} +1 -1
  49. package/dist/{chunk-27SGL3DF.js → chunk-KLPRF4PA.js} +1 -1
  50. package/dist/{chunk-QSPLYPVA.js → chunk-LJRXJHWJ.js} +1 -1
  51. package/dist/{chunk-YJPQBJZO.js → chunk-LWKHCQ46.js} +48 -3
  52. package/dist/{chunk-4P7NK7XM.js → chunk-MTKXD4WY.js} +2 -2
  53. package/dist/{chunk-JGRUCEL4.js → chunk-O7BPIPJB.js} +2 -2
  54. package/dist/{chunk-4UGM5YV4.js → chunk-ON7D53WE.js} +3 -3
  55. package/dist/{chunk-2DZYA62C.js → chunk-OTQFHUIH.js} +5 -5
  56. package/dist/{chunk-QFO7JHX2.js → chunk-PDS77GLS.js} +4 -4
  57. package/dist/{chunk-BNGGUL7F.js → chunk-PP7HR4II.js} +4 -4
  58. package/dist/{chunk-RXMGU7AF.js → chunk-PSRJYRAD.js} +8 -8
  59. package/dist/{chunk-F6W7FCS2.js → chunk-PTKFLEVN.js} +26 -2
  60. package/dist/{chunk-52NCZIAC.js → chunk-PZUMERGZ.js} +1 -1
  61. package/dist/{chunk-SCS7R2ND.js → chunk-QF5C3JXL.js} +128 -1
  62. package/dist/{chunk-WLIGKWVB.js → chunk-RFXO5GPB.js} +3 -3
  63. package/dist/{chunk-U65LWABS.js → chunk-SEBIXQEN.js} +7 -3
  64. package/dist/{chunk-G34BVUMF.js → chunk-SXDAIG5W.js} +1 -1
  65. package/dist/{chunk-Q4J3XSWE.js → chunk-TJ4UAO7R.js} +317 -7
  66. package/dist/{chunk-YDSY5YJE.js → chunk-TKX4G4NV.js} +4 -4
  67. package/dist/{chunk-L7TKNHEX.js → chunk-VRI3UDRA.js} +1 -1
  68. package/dist/{chunk-KWXARGCT.js → chunk-VWO4WRQM.js} +3 -3
  69. package/dist/{chunk-NWQQYLZV.js → chunk-WSFCQQ7F.js} +2717 -2111
  70. package/dist/{chunk-6IBLGQVZ.js → chunk-WUVX5HBI.js} +1 -1
  71. package/dist/{chunk-4TM4NXQR.js → chunk-X3UXPAT7.js} +2 -2
  72. package/dist/{chunk-TH3NNUJW.js → chunk-Y54KA37X.js} +5 -1
  73. package/dist/{citations-4LVBHTDX.js → citations-DAXUWNKQ.js} +3 -3
  74. package/dist/{cli-catalog-PJYR3JHX.js → cli-catalog-ORQPYKHI.js} +3 -3
  75. package/dist/{cli-commands-JBLV55EA.js → cli-commands-SDTHXYWU.js} +7 -7
  76. package/dist/cli.js +14 -14
  77. package/dist/{competitor-T7UXAW4F.js → competitor-QPL47DA6.js} +3 -3
  78. package/dist/{content-DFYYGGPI.js → content-V5NLV3AH.js} +3 -3
  79. package/dist/{dashboard-2P3TEH6S.js → dashboard-CZEO2UTG.js} +6 -6
  80. package/dist/{demo-F5TRWB6V.js → demo-JZS5DBSR.js} +1 -1
  81. package/dist/{demo-server-WIVTG6GH.js → demo-server-OAYVJVGC.js} +11 -11
  82. package/dist/{discover-QTC5OBQG.js → discover-TEEHJPLW.js} +3 -3
  83. package/dist/{discover-eval-QQZGUPR6.js → discover-eval-4I25W4VL.js} +3 -3
  84. package/dist/{doctor-VHFDL5MH.js → doctor-VR6YKJSW.js} +3 -3
  85. package/dist/{evidence-4PRFOC2I.js → evidence-SISRJ4YZ.js} +3 -3
  86. package/dist/{export-cmd-BQE7BPKZ.js → export-cmd-L5LKHKBY.js} +3 -3
  87. package/dist/{ga-ULY5XDBK.js → ga-WQQVWU5Q.js} +3 -3
  88. package/dist/{gbp-4WHNZAFY.js → gbp-XKRX7ZJY.js} +3 -3
  89. package/dist/{google-O4IVWLSG.js → google-TUEMVVGE.js} +4 -4
  90. package/dist/{google-marketing-DCQDTDDG.js → google-marketing-JWAJXNWR.js} +1 -1
  91. package/dist/{health-cmd-I2JTACS7.js → health-cmd-2OQEIQMG.js} +3 -3
  92. package/dist/{history-LUPHO3P3.js → history-33VEX442.js} +3 -3
  93. package/dist/index.d.ts +817 -63
  94. package/dist/index.js +24 -24
  95. package/dist/{init-LABWY7HI.js → init-QMLVST26.js} +11 -11
  96. package/dist/{insights-GC2W45U4.js → insights-6VIXDNVK.js} +3 -3
  97. package/dist/intelligence-service-NFBPBKI7.js +15 -0
  98. package/dist/journeys-7YJLJ34F.js +122 -0
  99. package/dist/{keys-DXQBSOBI.js → keys-I7Z5CGEQ.js} +3 -3
  100. package/dist/{keyword-2DCR2QCJ.js → keyword-OPTT3EXO.js} +3 -3
  101. package/dist/{logs-H45QFIEB.js → logs-35L2ZWRO.js} +3 -3
  102. package/dist/{mcp-NXXP6M3C.js → mcp-JWB42VTJ.js} +2 -2
  103. package/dist/mcp.js +9 -9
  104. package/dist/{measurement-plan-IG4JUKKW.js → measurement-plan-UWA2N6FO.js} +5 -5
  105. package/dist/{notify-BLLWXMBB.js → notify-FE7FSXDB.js} +3 -3
  106. package/dist/{organic-evidence-73K7W7SB.js → organic-evidence-34EKPGKI.js} +3 -3
  107. package/dist/{overview-4TAULPUG.js → overview-HPY5I6ZT.js} +4 -4
  108. package/dist/{project-ANX4JTWS.js → project-5CCX7VNR.js} +3 -3
  109. package/dist/{query-U3MFTLGR.js → query-VV4TRRDX.js} +3 -3
  110. package/dist/{research-3YZ6QI67.js → research-62VXIO2O.js} +3 -3
  111. package/dist/{results-export-72OVLKSC.js → results-export-QZQTNXMB.js} +3 -3
  112. package/dist/{run-SI6IL4FC.js → run-MYWJ2MPB.js} +4 -4
  113. package/dist/{schedule-FYEHU2VH.js → schedule-YC76OSAK.js} +3 -3
  114. package/dist/{search-MXDT3DQE.js → search-J2J7BXBL.js} +3 -3
  115. package/dist/{serve-3WJL5N2Z.js → serve-LESJD7GM.js} +56 -27
  116. package/dist/{session-VTFLD3C5.js → session-2MU6LLLC.js} +12 -12
  117. package/dist/{settings-ZGS26QOP.js → settings-QIMV3UYB.js} +3 -3
  118. package/dist/{skills-ZMMCKKSA.js → skills-3HOQ77ON.js} +2 -2
  119. package/dist/{snapshot-5AGGUQKE.js → snapshot-XL3KO4OW.js} +3 -3
  120. package/dist/{src-AIM5FPLZ.js → src-CLICUC3F.js} +8 -2
  121. package/dist/{status-HVQI4E5X.js → status-CKAJEBHG.js} +4 -4
  122. package/dist/{technical-aeo-S4OFCURE.js → technical-aeo-CW7WNDUU.js} +3 -3
  123. package/dist/{telemetry-SPSC5MUN.js → telemetry-GPP5XD7R.js} +4 -4
  124. package/dist/{tools-LRHO7QOT.js → tools-UNFFO5HO.js} +11 -11
  125. package/dist/{traffic-5AXVN37M.js → traffic-LALKHOSD.js} +5 -5
  126. package/dist/{users-WFKSUCGV.js → users-NQG7Y3GC.js} +3 -3
  127. package/dist/{visibility-stats-5S26GC27.js → visibility-stats-RJHXNYBM.js} +3 -3
  128. package/dist/{wordpress-IUPZC7II.js → wordpress-VLHQ6P47.js} +3 -3
  129. package/package.json +1 -1
  130. package/assets/assets/ToneBadge-DYEbxp5S.js +0 -60
  131. package/dist/intelligence-service-4PHEK5F4.js +0 -15
@@ -5,9 +5,10 @@ import {
5
5
  TrafficEvidenceKinds,
6
6
  TrafficSourceTypes,
7
7
  classifyAiReferralTrafficClass,
8
+ classifyJourneyEntry,
8
9
  hostMatchesDomain,
9
10
  hostOf
10
- } from "./chunk-Y7NX6EIK.js";
11
+ } from "./chunk-HUO3YPKB.js";
11
12
 
12
13
  // ../integration-traffic/src/ip-ranges/amazonbot.json
13
14
  var amazonbot_default = {
@@ -14506,14 +14507,321 @@ function classifyAiReferral(event) {
14506
14507
  return null;
14507
14508
  }
14508
14509
 
14510
+ // ../integration-traffic/src/journey.ts
14511
+ var ASSET_EXTENSION_PATTERN = /\.(?:avif|bmp|css|gif|ico|jpe?g|js|map|mjs|mp3|mp4|otf|png|svg|ttf|txt|webm|webmanifest|webp|woff2?|xml)$/i;
14512
+ var ASSET_PATH_PREFIXES = ["/_next/static/", "/_nuxt/", "/_ipx/", "/_vercel/", "/assets/", "/build/", "/dist/", "/fonts/", "/images/", "/img/", "/static/", "/wp-content/", "/wp-includes/", "/cdn-cgi/"];
14513
+ var DATA_PATH_PATTERN = /\.json$|^\/api\/|^\/wp-json\/|^\/graphql/i;
14514
+ var NON_BROWSER_PATTERN = /bot|crawl|spider|slurp|scrape|curl\/|wget|python|java\/|go-http|okhttp|axios|node-fetch|headless|phantom|lighthouse|pingdom|uptime|monitor|preview|facebookexternalhit|whatsapp|telegram|discord|slack/i;
14515
+ var KEPT_QUERY_PARAMETERS = ["utm_source", "utm_medium", "utm_campaign", "utm_term", "utm_content"];
14516
+ var AD_CLICK_ID_PARAMETERS = ["gclid", "gbraid", "wbraid", "dclid", "msclkid", "ttclid", "li_fat_id"];
14517
+ var NETWORK_CLICK_ID_PARAMETERS = { fbclid: "Facebook", twclid: "X" };
14518
+ var STEP_REFERER_HOSTS = [
14519
+ "accounts.google.com",
14520
+ "accounts.youtube.com",
14521
+ "pay.google.com",
14522
+ "appleid.apple.com",
14523
+ "login.microsoftonline.com",
14524
+ "login.live.com",
14525
+ "login.microsoft.com",
14526
+ "github.com/login",
14527
+ "checkout.stripe.com",
14528
+ "js.stripe.com",
14529
+ "hooks.stripe.com",
14530
+ "pay.stripe.com",
14531
+ "connect.stripe.com",
14532
+ "paypal.com",
14533
+ "pay.amazon.com",
14534
+ "checkout.shopify.com",
14535
+ "shop.app",
14536
+ "klarna.com",
14537
+ "afterpay.com",
14538
+ "squareup.com",
14539
+ "checkout.square.site",
14540
+ "adyen.com",
14541
+ "braintreegateway.com",
14542
+ "auth0.com",
14543
+ "okta.com",
14544
+ "onelogin.com",
14545
+ "amazoncognito.com",
14546
+ "clerk.accounts.dev"
14547
+ ];
14548
+ var MAX_PATH_LENGTH = 512;
14549
+ var UUID_SEGMENT = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
14550
+ var LONG_HEX_SEGMENT = /^[0-9a-f]{16,}$/i;
14551
+ var TOKEN_CHARSET = /^[\w-]+$/;
14552
+ var JWT_SEGMENT = /^eyJ[\w-]+\.[\w-]+/;
14553
+ function baseHost(host) {
14554
+ const h = host?.trim().toLowerCase().replace(/:\d+$/, "").replace(/^www\./, "").replace(/\.$/, "");
14555
+ return h || null;
14556
+ }
14557
+ function domainOf(value) {
14558
+ const v = value.trim().toLowerCase();
14559
+ if (!v) return null;
14560
+ try {
14561
+ return baseHost(new URL(v.includes("://") ? v : `https://${v}`).hostname);
14562
+ } catch {
14563
+ return null;
14564
+ }
14565
+ }
14566
+ function refererUrlOf(referer) {
14567
+ if (!referer) return null;
14568
+ try {
14569
+ return new URL(referer);
14570
+ } catch {
14571
+ return null;
14572
+ }
14573
+ }
14574
+ function hostOfEvent(event) {
14575
+ if (event.host) return event.host;
14576
+ if (!event.requestUrl) return null;
14577
+ try {
14578
+ return new URL(event.requestUrl).hostname || null;
14579
+ } catch {
14580
+ return null;
14581
+ }
14582
+ }
14583
+ var onDomain = (host, domain) => host === domain || host.endsWith(`.${domain}`);
14584
+ function isStepRefererHost(host, path) {
14585
+ return STEP_REFERER_HOSTS.some((entry) => {
14586
+ const slash = entry.indexOf("/");
14587
+ if (slash < 0) return onDomain(host, entry);
14588
+ return host === entry.slice(0, slash) && path.startsWith(entry.slice(slash));
14589
+ });
14590
+ }
14591
+ function isAssetPath(path) {
14592
+ return ASSET_PATH_PREFIXES.some((prefix) => path.startsWith(prefix)) || ASSET_EXTENSION_PATTERN.test(path);
14593
+ }
14594
+ function looksSecret(segment) {
14595
+ if (UUID_SEGMENT.test(segment) || LONG_HEX_SEGMENT.test(segment) || JWT_SEGMENT.test(segment)) return true;
14596
+ if (segment.length < 20 || !TOKEN_CHARSET.test(segment)) return false;
14597
+ const digits = segment.replace(/\D/g, "").length;
14598
+ const letters = segment.replace(/[^a-z]/gi, "").length;
14599
+ const mixedCase = /[a-z]/.test(segment) && /[A-Z]/.test(segment);
14600
+ return digits >= 3 && letters >= 3 && (mixedCase || !/[-_]/.test(segment));
14601
+ }
14602
+ function maskJourneyPath(path) {
14603
+ return (path || "/").split("/").map((raw) => {
14604
+ const segment = raw.split(";")[0];
14605
+ if (!segment) return segment;
14606
+ if (/@|%40/.test(segment)) return ":email";
14607
+ return looksSecret(segment) ? ":token" : segment;
14608
+ }).join("/") || "/";
14609
+ }
14610
+ function isLikelyBrowser(userAgent) {
14611
+ const ua = userAgent?.trim();
14612
+ return Boolean(ua) && /^Mozilla\//.test(ua) && !NON_BROWSER_PATTERN.test(ua);
14613
+ }
14614
+ function extractJourneyRequests(events, options = {}) {
14615
+ const siteDomains = (options.siteDomains ?? []).map(domainOf).filter((d) => Boolean(d));
14616
+ const out = [];
14617
+ for (const event of events) {
14618
+ const method = event.method?.toUpperCase() ?? null;
14619
+ if (method === "HEAD" || method === "OPTIONS") continue;
14620
+ const observedMs = Date.parse(event.observedAt);
14621
+ if (!Number.isFinite(observedMs)) continue;
14622
+ const rawPath = event.path.split("?")[0] || "/";
14623
+ if (isAssetPath(rawPath)) continue;
14624
+ if (!isLikelyBrowser(event.userAgent)) continue;
14625
+ if (isSelfTraffic(event) || classifyCrawler(event) || classifyAiUserFetch(event)) continue;
14626
+ const params = new URLSearchParams(event.queryString ?? "");
14627
+ const kept = KEPT_QUERY_PARAMETERS.flatMap((name) => {
14628
+ const value = params.get(name);
14629
+ return value ? [`${name}=${encodeURIComponent(value)}`] : [];
14630
+ });
14631
+ const maskedPath = maskJourneyPath(rawPath);
14632
+ const path = (kept.length ? `${maskedPath}?${kept.join("&")}` : maskedPath).slice(0, MAX_PATH_LENGTH);
14633
+ const refererUrl = refererUrlOf(event.referer);
14634
+ const refererHost = refererUrl?.hostname || null;
14635
+ const refererBase = baseHost(refererHost);
14636
+ const siteHost = baseHost(hostOfEvent(event));
14637
+ const sameSite = Boolean(refererBase && (siteHost && (onDomain(refererBase, siteHost) || onDomain(siteHost, refererBase)) || siteDomains.some((domain) => onDomain(refererBase, domain))));
14638
+ const stepReferer = sameSite || Boolean(refererBase && isStepRefererHost(refererBase, refererUrl?.pathname ?? "/"));
14639
+ const ai = classifyAiReferral(event);
14640
+ const networkClickId = Object.keys(NETWORK_CLICK_ID_PARAMETERS).find((name) => params.has(name));
14641
+ out.push({
14642
+ eventId: event.eventId,
14643
+ observedAt: new Date(observedMs).toISOString(),
14644
+ method,
14645
+ path,
14646
+ status: event.status,
14647
+ kind: DATA_PATH_PATTERN.test(rawPath) ? "data" : "page",
14648
+ remoteIp: event.remoteIp?.trim() || null,
14649
+ userAgent: event.userAgent.trim(),
14650
+ stepReferer,
14651
+ aiEvidence: ai?.evidenceType ?? null,
14652
+ signal: {
14653
+ aiProduct: ai?.product ?? null,
14654
+ aiDomain: ai?.sourceDomain ?? null,
14655
+ aiPaid: ai?.trafficClass === "paid",
14656
+ refererHost: stepReferer ? null : refererHost,
14657
+ utmSource: params.get("utm_source"),
14658
+ utmMedium: params.get("utm_medium"),
14659
+ adClickId: AD_CLICK_ID_PARAMETERS.some((name) => params.has(name)),
14660
+ clickNetwork: networkClickId ? NETWORK_CLICK_ID_PARAMETERS[networkClickId] : null
14661
+ }
14662
+ });
14663
+ }
14664
+ return out;
14665
+ }
14666
+ function hasEntryEvidence(request) {
14667
+ if (request.stepReferer) return false;
14668
+ const s = request.signal;
14669
+ return Boolean(s.aiProduct || s.refererHost || s.utmSource || s.utmMedium || s.adClickId || s.clickNetwork);
14670
+ }
14671
+ function entryKey(entry) {
14672
+ return `${entry.entryClass}:${entry.entryName ?? entry.entryHost ?? ""}`;
14673
+ }
14674
+ var ms = (iso) => Date.parse(iso);
14675
+ var DIRECT_ENTRY = { entryClass: "direct", entryName: null, entryHost: null, paid: false };
14676
+ var laterOf = (a, b) => a !== null && a > b ? a : b;
14677
+ function placeRequest(visits, t, outsideEntry, idleMs) {
14678
+ let current;
14679
+ let next;
14680
+ for (const v of visits) {
14681
+ const start = ms(v.startedAt);
14682
+ if (start <= t) {
14683
+ if (t <= ms(v.endedAt) + idleMs && (!current || v.startedAt > current.startedAt)) current = v;
14684
+ } else if (start - t <= idleMs && (!next || v.startedAt < next.startedAt)) {
14685
+ next = v;
14686
+ }
14687
+ }
14688
+ if (current && (outsideEntry === null || outsideEntry === entryKey(current.entry))) return { visit: current, head: false, current };
14689
+ if (next && (next.entry.entryClass === "direct" || outsideEntry === entryKey(next.entry))) return { visit: next, head: true, current };
14690
+ return { visit: void 0, head: false, current };
14691
+ }
14692
+ function insertSorted(values, value) {
14693
+ let i = values.length;
14694
+ while (i > 0 && values[i - 1] > value) i -= 1;
14695
+ if (values[i - 1] !== value) values.splice(i, 0, value);
14696
+ }
14697
+ function sessionizeJourneyRequests(requests, state, options) {
14698
+ const byVisitor = /* @__PURE__ */ new Map();
14699
+ for (const request of requests) {
14700
+ const list = byVisitor.get(request.visitorKey);
14701
+ if (list) list.push(request);
14702
+ else byVisitor.set(request.visitorKey, [request]);
14703
+ }
14704
+ const visits = /* @__PURE__ */ new Map();
14705
+ const events = [];
14706
+ const visitors = [];
14707
+ let dropped = 0;
14708
+ let capped = 0;
14709
+ for (const [visitorKey, list] of byVisitor) {
14710
+ list.sort((a, b) => a.observedAt < b.observedAt ? -1 : a.observedAt > b.observedAt ? 1 : 0);
14711
+ const prior = state.get(visitorKey);
14712
+ const isWeakAi = (r) => Boolean(r.signal.aiProduct) && r.stepReferer;
14713
+ const isStrongAi = (r) => Boolean(r.signal.aiProduct) && !r.stepReferer;
14714
+ const aiTimes = [...new Set([
14715
+ prior?.firstAiAt,
14716
+ prior?.lastAiAt,
14717
+ ...prior?.aiTimes ?? [],
14718
+ ...list.filter(isStrongAi).map((r) => r.observedAt)
14719
+ ].filter((t) => Boolean(t)))].sort();
14720
+ if (aiTimes.length === 0 && !list.some(isWeakAi)) {
14721
+ dropped += list.length;
14722
+ continue;
14723
+ }
14724
+ const engineAt = /* @__PURE__ */ new Map();
14725
+ const known = (prior?.visits ?? []).map((v) => ({ ...v, visitorKey, landingPath: "", isNew: false, headChanged: false }));
14726
+ const requestsByDay = new Map(Object.entries(prior?.requestsByDay ?? {}));
14727
+ let keptAny = false;
14728
+ const cappedDays = /* @__PURE__ */ new Set();
14729
+ let lastSeenAt = null;
14730
+ let userAgent = list[0].userAgent;
14731
+ let aiIndex = -1;
14732
+ for (const request of list) {
14733
+ const t = ms(request.observedAt);
14734
+ while (aiIndex + 1 < aiTimes.length && aiTimes[aiIndex + 1] <= request.observedAt) aiIndex += 1;
14735
+ const withinLookback = aiIndex >= 0 && t - ms(aiTimes[aiIndex]) <= options.lookbackMs;
14736
+ let aiTouch = isStrongAi(request);
14737
+ if (isWeakAi(request) && !withinLookback) {
14738
+ aiTouch = true;
14739
+ insertSorted(aiTimes, request.observedAt);
14740
+ aiIndex = aiTimes.indexOf(request.observedAt);
14741
+ }
14742
+ if (aiTouch && request.signal.aiProduct && !engineAt.has(request.observedAt)) engineAt.set(request.observedAt, request.signal.aiProduct);
14743
+ const entry = aiTouch ? classifyJourneyEntry(request.signal) : request.stepReferer ? DIRECT_ENTRY : classifyJourneyEntry({ ...request.signal, aiProduct: null, aiDomain: null, aiPaid: false });
14744
+ const outside = aiTouch || hasEntryEvidence(request);
14745
+ const placement = placeRequest(known, t, outside ? entryKey(entry) : null, options.idleMs);
14746
+ const continues = placement.visit !== void 0 && !placement.head;
14747
+ const kept = aiTouch || withinLookback || continues;
14748
+ const opensVisit = placement.visit === void 0;
14749
+ if (!kept || opensVisit && request.kind === "data" && !outside) {
14750
+ dropped += 1;
14751
+ continue;
14752
+ }
14753
+ const day = request.observedAt.slice(0, 10);
14754
+ const stored = requestsByDay.get(day) ?? 0;
14755
+ if (stored >= options.maxRequestsPerDay && !aiTouch) {
14756
+ cappedDays.add(day);
14757
+ capped += 1;
14758
+ continue;
14759
+ }
14760
+ requestsByDay.set(day, stored + 1);
14761
+ let target;
14762
+ if (placement.visit) {
14763
+ target = placement.visit;
14764
+ if (placement.head) {
14765
+ target.startedAt = request.observedAt;
14766
+ target.landingPath = request.path;
14767
+ if (outside) target.entry = entry;
14768
+ target.headChanged = !target.isNew;
14769
+ }
14770
+ if (request.observedAt > target.endedAt) target.endedAt = request.observedAt;
14771
+ target.requestCount += 1;
14772
+ if (request.kind === "page") target.pageCount += 1;
14773
+ } else {
14774
+ target = {
14775
+ id: options.newId(),
14776
+ visitorKey,
14777
+ startedAt: request.observedAt,
14778
+ endedAt: request.observedAt,
14779
+ entry,
14780
+ requestCount: 1,
14781
+ pageCount: request.kind === "page" ? 1 : 0,
14782
+ landingPath: request.path,
14783
+ isNew: true,
14784
+ headChanged: false
14785
+ };
14786
+ const inside = placement.current;
14787
+ if (outside && inside && request.observedAt < inside.endedAt) {
14788
+ target.splitFrom = { visitId: inside.id, after: request.observedAt };
14789
+ target.endedAt = inside.endedAt;
14790
+ inside.endedAt = request.observedAt;
14791
+ visits.set(inside.id, inside);
14792
+ }
14793
+ known.push(target);
14794
+ }
14795
+ visits.set(target.id, target);
14796
+ events.push({ visitId: target.id, visitorKey, request, aiTouch });
14797
+ keptAny = true;
14798
+ lastSeenAt = laterOf(lastSeenAt, request.observedAt);
14799
+ userAgent = request.userAgent;
14800
+ }
14801
+ if ((keptAny || cappedDays.size > 0) && aiTimes.length > 0) {
14802
+ const firstAiAt = aiTimes[0];
14803
+ visitors.push({
14804
+ visitorKey,
14805
+ firstAiAt,
14806
+ firstAiEngine: (prior?.firstAiAt === firstAiAt ? prior?.firstAiEngine : null) ?? engineAt.get(firstAiAt) ?? prior?.firstAiEngine ?? "AI",
14807
+ lastAiAt: aiTimes[aiTimes.length - 1],
14808
+ userAgent,
14809
+ lastSeenAt: lastSeenAt ?? prior?.lastAiAt ?? firstAiAt,
14810
+ cappedDays: [...cappedDays].sort()
14811
+ });
14812
+ }
14813
+ }
14814
+ return { visits: [...visits.values()], events, visitors, dropped, capped };
14815
+ }
14816
+
14509
14817
  // ../integration-traffic/src/rollup.ts
14510
14818
  var DEFAULT_SAMPLE_LIMIT = 25;
14511
14819
  var DEFAULT_AI_REFERRAL_SESSION_WINDOW_MS = 6e4;
14512
- var UUID_SEGMENT = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
14513
- var LONG_HEX_SEGMENT = /^[0-9a-f]{16,}$/i;
14820
+ var UUID_SEGMENT2 = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
14821
+ var LONG_HEX_SEGMENT2 = /^[0-9a-f]{16,}$/i;
14514
14822
  var NUMERIC_SEGMENT = /^\d+$/;
14515
- var ASSET_EXTENSION_PATTERN = /\.(?:avif|bmp|css|gif|ico|jpe?g|js|json|map|mjs|mp4|otf|png|svg|webm|webmanifest|woff2?|xml)$/i;
14516
- var ASSET_PATH_PREFIXES = [
14823
+ var ASSET_EXTENSION_PATTERN2 = /\.(?:avif|bmp|css|gif|ico|jpe?g|js|json|map|mjs|mp4|otf|png|svg|webm|webmanifest|woff2?|xml)$/i;
14824
+ var ASSET_PATH_PREFIXES2 = [
14517
14825
  "/_next/static/",
14518
14826
  "/assets/",
14519
14827
  "/build/",
@@ -14528,7 +14836,7 @@ function normalizeTrafficPathPattern(path) {
14528
14836
  const pathOnly = cleanPath.split("?")[0] || "/";
14529
14837
  const segments = pathOnly.split("/").map((segment) => {
14530
14838
  if (!segment) return segment;
14531
- if (UUID_SEGMENT.test(segment) || LONG_HEX_SEGMENT.test(segment) || NUMERIC_SEGMENT.test(segment)) {
14839
+ if (UUID_SEGMENT2.test(segment) || LONG_HEX_SEGMENT2.test(segment) || NUMERIC_SEGMENT.test(segment)) {
14532
14840
  return ":id";
14533
14841
  }
14534
14842
  return segment;
@@ -14571,7 +14879,7 @@ function resolveAiReferralLandingPath(event, evidenceType) {
14571
14879
  }
14572
14880
  function isLikelySubresourcePath(path) {
14573
14881
  const cleanPath = path.split("?")[0] || "/";
14574
- return ASSET_PATH_PREFIXES.some((prefix) => cleanPath.startsWith(prefix)) || ASSET_EXTENSION_PATTERN.test(cleanPath);
14882
+ return ASSET_PATH_PREFIXES2.some((prefix) => cleanPath.startsWith(prefix)) || ASSET_EXTENSION_PATTERN2.test(cleanPath);
14575
14883
  }
14576
14884
  function actorKey(event) {
14577
14885
  const remoteIp = event.remoteIp?.trim();
@@ -15364,6 +15672,8 @@ export {
15364
15672
  isSelfTraffic,
15365
15673
  classifyCrawler,
15366
15674
  classifyAiUserFetch,
15675
+ extractJourneyRequests,
15676
+ sessionizeJourneyRequests,
15367
15677
  buildTrafficProbeReport,
15368
15678
  normalizeCloudflareWorkerEvent,
15369
15679
  CLOUDFLARE_WORKER_BINDINGS,
@@ -2,13 +2,13 @@ import {
2
2
  bucketCliCommandDuration,
3
3
  isTelemetryEnabled,
4
4
  trackEvent
5
- } from "./chunk-IFVTHGXG.js";
5
+ } from "./chunk-EJZ4TQQR.js";
6
6
  import {
7
7
  getConfigDir
8
- } from "./chunk-TVANRUBO.js";
8
+ } from "./chunk-FA7RDZ43.js";
9
9
  import {
10
10
  currentOutcomeAttribution
11
- } from "./chunk-27SGL3DF.js";
11
+ } from "./chunk-KLPRF4PA.js";
12
12
  import {
13
13
  AGENT_NONE,
14
14
  OutcomeSurfaces,
@@ -19,7 +19,7 @@ import {
19
19
  integrationConnectionPropertiesSchema,
20
20
  normalizeAgentSlug,
21
21
  usageSurfaceSchema
22
- } from "./chunk-Y7NX6EIK.js";
22
+ } from "./chunk-HUO3YPKB.js";
23
23
 
24
24
  // src/outcome-telemetry.ts
25
25
  import fs from "fs";
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  hostMatchesDomain
3
- } from "./chunk-Y7NX6EIK.js";
3
+ } from "./chunk-HUO3YPKB.js";
4
4
 
5
5
  // src/citation-utils.ts
6
6
  function pickProjectCitedDomain(citedDomains, projectDomains) {
@@ -6,12 +6,12 @@ import {
6
6
  import {
7
7
  createApiClient,
8
8
  runWithUsageTags
9
- } from "./chunk-F6W7FCS2.js";
9
+ } from "./chunk-PTKFLEVN.js";
10
10
  import {
11
11
  canonryMcpTools,
12
12
  mcpOutputSchema,
13
13
  toolOperationAccess
14
- } from "./chunk-YJPQBJZO.js";
14
+ } from "./chunk-LWKHCQ46.js";
15
15
  import {
16
16
  PACKAGE_VERSION
17
17
  } from "./chunk-AOJU5LKX.js";
@@ -24,7 +24,7 @@ import {
24
24
  isReadOnlyKey,
25
25
  restrictedWriteScopes,
26
26
  upgradeCaveatFor
27
- } from "./chunk-Y7NX6EIK.js";
27
+ } from "./chunk-HUO3YPKB.js";
28
28
 
29
29
  // src/mcp/server.ts
30
30
  import { randomUUID } from "crypto";