@canonry/canonry 7.83.2 → 7.85.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 (136) hide show
  1. package/assets/agent-workspace/skills/aero/references/ai-traffic-tracking.md +2 -1
  2. package/assets/agent-workspace/skills/canonry/references/ai-traffic-tracking.md +2 -1
  3. package/assets/agent-workspace/skills/canonry/references/canonry-cli.md +4 -0
  4. package/assets/agent-workspace/skills/canonry/references/server-side-traffic.md +45 -8
  5. package/assets/assets/{AgentSetupPage-B9NOQP8a.js → AgentSetupPage-NdqmQkYa.js} +1 -1
  6. package/assets/assets/{AuditHistoryPanel-Fvh4WFjq.js → AuditHistoryPanel-CuqdFCb9.js} +1 -1
  7. package/assets/assets/{BacklinksPage-D1UHFLoV.js → BacklinksPage-CVjZiG1i.js} +1 -1
  8. package/assets/assets/{HistoryPage-CBcacDgP.js → HistoryPage-DRvdgemW.js} +1 -1
  9. package/assets/assets/{MeasurementPropertyPage-ZuZpurwr.js → MeasurementPropertyPage-Bc5EpJFV.js} +1 -1
  10. package/assets/assets/{ProjectPage-BoqDyoGi.js → ProjectPage-CGGBSiK7.js} +1 -1
  11. package/assets/assets/{RunsPage-tlCk_gOw.js → RunsPage-B6_o81G3.js} +1 -1
  12. package/assets/assets/{SettingsPage-7mRTFLFQ.js → SettingsPage-DjmVapHO.js} +1 -1
  13. package/assets/assets/{SiteHealthSection-l_A_AmY_.js → SiteHealthSection-BPPB0D9D.js} +2 -2
  14. package/assets/assets/{ToneBadge-CXyUIWzB.js → ToneBadge-DwUBSAjL.js} +1 -1
  15. package/assets/assets/{TrafficPage-DQbBT3TP.js → TrafficPage-BvbjxOw3.js} +1 -1
  16. package/assets/assets/{TrafficSourceDetailPage-D3DwE6Qd.js → TrafficSourceDetailPage-BGJwxS_Q.js} +1 -1
  17. package/assets/assets/{account-context-Bhgg1lEH.js → account-context-D7M4W4wP.js} +1 -1
  18. package/assets/assets/agent-trust-copy-WXXeDvDs.js +1 -0
  19. package/assets/assets/{card-B16Dvxau.js → card-DULVRmzI.js} +1 -1
  20. package/assets/assets/{extract-error-message-B5_v_-U8.js → extract-error-message-B9-6WgLm.js} +1 -1
  21. package/assets/assets/{format-helpers-Bs9rrO74.js → format-helpers-Cgq0VzXz.js} +1 -1
  22. package/assets/assets/{index-3aBRkQpI.js → index-A-4JN4Pv.js} +4 -4
  23. package/assets/assets/{query-client-D-tt1sn3.js → query-client-1Q6EwPba.js} +1 -1
  24. package/assets/assets/{react-query-DQr9PoNm.js → react-query-D0OiMBt3.js} +1 -1
  25. package/assets/assets/{react-sigma_core.esm.min-BfZVKh7v.js → react-sigma_core.esm.min-CR09uPhZ.js} +1 -1
  26. package/assets/assets/{service-Cmt36bhL.js → service-Bu-7icpb.js} +1 -1
  27. package/assets/index.html +7 -7
  28. package/dist/{ads-BSVYKQ2L.js → ads-ETZIGLL5.js} +3 -3
  29. package/dist/{agent-L7VUHOHS.js → agent-WG2FUC7C.js} +7 -7
  30. package/dist/{agent-ask-A4HQCNLV.js → agent-ask-775XBFOH.js} +3 -3
  31. package/dist/{agent-conversations-L3TJJKPJ.js → agent-conversations-AYZ3LQJQ.js} +3 -3
  32. package/dist/{agent-journeys-FEXRAZYN.js → agent-journeys-GWNZG73C.js} +3 -3
  33. package/dist/{agent-memory-LBTLOHUA.js → agent-memory-E5MRRS5P.js} +3 -3
  34. package/dist/{agent-providers-X7V2IHRK.js → agent-providers-DEQZWO2M.js} +3 -3
  35. package/dist/{agent-transcript-YSP2HKUZ.js → agent-transcript-4AKVVHQC.js} +3 -3
  36. package/dist/{analytics-FBPHES6M.js → analytics-HSLTWKDA.js} +3 -3
  37. package/dist/{apply-PBCXZC5F.js → apply-4GD7VGG7.js} +3 -3
  38. package/dist/{backfill-PZBLCRPI.js → backfill-LNE2BW34.js} +10 -9
  39. package/dist/{backlinks-QMLTF2VF.js → backlinks-TGE3DWA2.js} +3 -3
  40. package/dist/{bing-H65WGTXU.js → bing-56GNRC55.js} +3 -3
  41. package/dist/{bootstrap-JAZNMAKP.js → bootstrap-42XCWZTS.js} +10 -10
  42. package/dist/{cdp-4DAMAHTB.js → cdp-UODIMKE3.js} +7 -7
  43. package/dist/{chunk-UGUON7IK.js → chunk-2O5XBKEO.js} +7 -7
  44. package/dist/{chunk-IQTMHY23.js → chunk-2R6WI237.js} +17643 -17454
  45. package/dist/{chunk-OMNS42ZQ.js → chunk-2X6UAPAC.js} +523 -4
  46. package/dist/{chunk-SEAXXCU6.js → chunk-4KK3OTHE.js} +1 -1
  47. package/dist/{chunk-X7U7XYJQ.js → chunk-5NEZO3SC.js} +3 -3
  48. package/dist/{chunk-SVMTN7MI.js → chunk-6SGHSSWQ.js} +2 -2
  49. package/dist/{chunk-NCM6PX64.js → chunk-AICFUZ6X.js} +1 -1
  50. package/dist/{chunk-QAJDHHC5.js → chunk-BQTXXXUG.js} +1 -1
  51. package/dist/{chunk-V52KSHH7.js → chunk-C2H5TPKD.js} +338 -338
  52. package/dist/{chunk-IJQJSNOZ.js → chunk-D45AMUYA.js} +4 -4
  53. package/dist/{chunk-WA4FD5Y6.js → chunk-DWK6NIJF.js} +1 -1
  54. package/dist/{chunk-CBAYQHNX.js → chunk-GR7VVRNN.js} +1 -1
  55. package/dist/{chunk-SKH3N6WI.js → chunk-IOW23XNK.js} +3 -3
  56. package/dist/{chunk-5AGYH5PX.js → chunk-JVO5GQZH.js} +4287 -3934
  57. package/dist/{chunk-3GXAL3F7.js → chunk-KBLMQDUZ.js} +37 -171
  58. package/dist/{chunk-PHVIMUAQ.js → chunk-KNKOTLVW.js} +6 -2
  59. package/dist/{chunk-3UFQI4KL.js → chunk-L5R5S57T.js} +75 -1
  60. package/dist/{chunk-32U5LFIT.js → chunk-NY252PIY.js} +3 -3
  61. package/dist/{chunk-W5ZBMBBZ.js → chunk-OHDSI5XS.js} +1 -1
  62. package/dist/{chunk-KCFIQJOL.js → chunk-OS5BVALI.js} +2 -2
  63. package/dist/{chunk-AA6P5NK3.js → chunk-PQWZCAVS.js} +1 -1
  64. package/dist/{chunk-WDEDEEWA.js → chunk-PX2KVGOJ.js} +1 -1
  65. package/dist/{chunk-HIC62JTS.js → chunk-Q7354YI3.js} +3 -3
  66. package/dist/{chunk-KFMU6CLU.js → chunk-QEATYB7C.js} +1 -1
  67. package/dist/{chunk-Y7WHB65J.js → chunk-RCAB7M6A.js} +2 -2
  68. package/dist/{chunk-LZGVQSZL.js → chunk-SS33RWKG.js} +1 -1
  69. package/dist/{chunk-YCRPOY2Y.js → chunk-TPUBPXBN.js} +2 -2
  70. package/dist/{chunk-QHUCHZA3.js → chunk-TVZMFCX2.js} +6 -6
  71. package/dist/{chunk-4D2QHIRS.js → chunk-UMEQ7EYN.js} +4 -4
  72. package/dist/{chunk-IPPNN5KE.js → chunk-UMV4HYHD.js} +2 -2
  73. package/dist/{chunk-7Q5BSCKN.js → chunk-VFSHZHZS.js} +2 -2
  74. package/dist/{chunk-YJOGWS7F.js → chunk-X7XKMARG.js} +2 -2
  75. package/dist/{chunk-KVSCEZBR.js → chunk-YDC2V5FQ.js} +30 -25
  76. package/dist/{chunk-JCWXEVYW.js → chunk-Z53CKLDS.js} +3 -3
  77. package/dist/{chunk-P76XOEWL.js → chunk-ZXMDIWW6.js} +4 -4
  78. package/dist/{citations-MNLMO33V.js → citations-RXBPR5MX.js} +3 -3
  79. package/dist/{cli-catalog-IKF4A7ZS.js → cli-catalog-QVCJWPCI.js} +3 -3
  80. package/dist/{cli-commands-KNMPQFQO.js → cli-commands-ZXR4Z2RW.js} +7 -7
  81. package/dist/cli.js +13 -13
  82. package/dist/{competitor-5DY5PKNU.js → competitor-MDNNHRSD.js} +3 -3
  83. package/dist/{content-XNK2YY4S.js → content-D3JZZQ64.js} +3 -3
  84. package/dist/{dashboard-SMI6A6OF.js → dashboard-5S2A46GM.js} +6 -6
  85. package/dist/{demo-DIP5JBEI.js → demo-DQHWRIKR.js} +1 -1
  86. package/dist/{demo-server-EWOBWWV4.js → demo-server-FY2XBSD2.js} +12 -12
  87. package/dist/{discover-D4H4ALIE.js → discover-NVNWHOTZ.js} +3 -3
  88. package/dist/{discover-eval-2CID2IBT.js → discover-eval-CJB6GYUS.js} +3 -3
  89. package/dist/{doctor-OWRQNDWF.js → doctor-DLSKNC4W.js} +3 -3
  90. package/dist/{evidence-SQX4IMQM.js → evidence-QNJULIXM.js} +3 -3
  91. package/dist/{export-cmd-73PYMZZ5.js → export-cmd-Z2YG2WLK.js} +3 -3
  92. package/dist/{ga-S6AKEVAL.js → ga-RSNHBP2B.js} +3 -3
  93. package/dist/{gbp-57J3AXEY.js → gbp-ZEV62LSZ.js} +3 -3
  94. package/dist/{google-PPU5MJSV.js → google-RZHEIKW5.js} +4 -4
  95. package/dist/{google-marketing-W4KZ74HX.js → google-marketing-DYQXPTD3.js} +1 -1
  96. package/dist/{health-cmd-QYP4MS3E.js → health-cmd-6ATPYUYG.js} +3 -3
  97. package/dist/{history-MFHBHYH7.js → history-KLX6XRY4.js} +3 -3
  98. package/dist/index.d.ts +337 -47
  99. package/dist/index.js +25 -25
  100. package/dist/{init-UZPL4H55.js → init-5BALV6SU.js} +12 -12
  101. package/dist/{insights-IIMMXGRO.js → insights-ARCEFFK5.js} +3 -3
  102. package/dist/intelligence-service-YJFZ6IBI.js +16 -0
  103. package/dist/{journeys-DXXRNANM.js → journeys-WVRQRZQJ.js} +3 -3
  104. package/dist/{keys-O3T52MLX.js → keys-5KAJFRZZ.js} +3 -3
  105. package/dist/{keyword-MS23BR7O.js → keyword-PTUH3TFD.js} +3 -3
  106. package/dist/{logs-SKR5OLTY.js → logs-NM7ACXGQ.js} +3 -3
  107. package/dist/{mcp-NFC2PBGD.js → mcp-ALRQXYL3.js} +4 -4
  108. package/dist/mcp.js +9 -9
  109. package/dist/{measurement-plan-Z73LMQYB.js → measurement-plan-T52JHK2J.js} +5 -5
  110. package/dist/{notify-2RUWK2AR.js → notify-MJBMRDXD.js} +3 -3
  111. package/dist/{organic-evidence-BGAOEVMZ.js → organic-evidence-ZUCQFWD5.js} +3 -3
  112. package/dist/{overview-DONWVYZT.js → overview-74IHPU2A.js} +4 -4
  113. package/dist/{project-FFSPWR6R.js → project-DKQOPMH6.js} +3 -3
  114. package/dist/{query-AXEUWIW3.js → query-YDJ5T46L.js} +3 -3
  115. package/dist/{research-YURAJRCV.js → research-5DU6DFZW.js} +3 -3
  116. package/dist/{results-export-ECSJKZHZ.js → results-export-EDVVXKVW.js} +3 -3
  117. package/dist/{run-27EXPBE4.js → run-HRHGSIYE.js} +4 -4
  118. package/dist/{schedule-NY55SZZF.js → schedule-GZVKQGMP.js} +3 -3
  119. package/dist/{search-RXCBX3ST.js → search-M37GRKVC.js} +3 -3
  120. package/dist/{serve-KGZW5WPA.js → serve-DW6PPZPJ.js} +26 -26
  121. package/dist/{session-BY2FSRYU.js → session-H427H2SK.js} +13 -13
  122. package/dist/{settings-IPC5SSDU.js → settings-WGS7GP7C.js} +3 -3
  123. package/dist/{skills-Y3VNCWQM.js → skills-CDDUPMAU.js} +2 -2
  124. package/dist/{snapshot-TPDSMADU.js → snapshot-5MAK7PWE.js} +3 -3
  125. package/dist/{src-IDX2F2SR.js → src-FEV4KYXN.js} +8 -2
  126. package/dist/{status-YSQJBNM7.js → status-EHFOYTXQ.js} +4 -4
  127. package/dist/{technical-aeo-NMUQVIFG.js → technical-aeo-KVY4RQWT.js} +3 -3
  128. package/dist/{telemetry-OA6W7Q54.js → telemetry-7XRRIHVC.js} +4 -4
  129. package/dist/{tools-5YRH5NEI.js → tools-EHONHGB6.js} +11 -11
  130. package/dist/{traffic-CE47IFFI.js → traffic-TBR6GOWN.js} +5 -5
  131. package/dist/{users-NMWBTCDI.js → users-YQS4X47Q.js} +3 -3
  132. package/dist/{visibility-stats-DE64FVOJ.js → visibility-stats-JXIOSJXC.js} +3 -3
  133. package/dist/{wordpress-AJWIJSM7.js → wordpress-HVOLEPQY.js} +3 -3
  134. package/package.json +1 -1
  135. package/assets/assets/agent-trust-copy-CKZsKhc0.js +0 -1
  136. package/dist/intelligence-service-AMXDCTS2.js +0 -16
@@ -1,40 +1,34 @@
1
1
  import {
2
2
  OPENAI_RETRIEVAL_CONTRACT,
3
3
  openrouterAdapter,
4
+ reclassifyStoredTraffic,
4
5
  reparseStoredResult,
5
6
  reparseStoredResult2,
6
7
  reparseStoredResult3,
7
8
  reparseStoredResult4,
8
9
  reparseStoredResult5,
9
10
  resolveStoredApiResponse
10
- } from "./chunk-OMNS42ZQ.js";
11
+ } from "./chunk-2X6UAPAC.js";
11
12
  import {
12
13
  loadConfig
13
- } from "./chunk-WA4FD5Y6.js";
14
+ } from "./chunk-DWK6NIJF.js";
14
15
  import {
15
16
  isMachineFormat
16
17
  } from "./chunk-HGMYEDAQ.js";
17
18
  import {
18
19
  determineCitationState
19
- } from "./chunk-LZGVQSZL.js";
20
+ } from "./chunk-SS33RWKG.js";
20
21
  import {
21
- addLikelyFakeAgentHits,
22
22
  backfillProjectAnswerMentions,
23
23
  competitorIdentityColumns,
24
24
  createRunCompetitorResolver,
25
25
  readMarketCompetitorNames,
26
26
  refreshSnapshotMentionIdentity
27
- } from "./chunk-5AGYH5PX.js";
28
- import {
29
- classifyAiUserFetch,
30
- classifyCrawler
31
- } from "./chunk-IQTMHY23.js";
27
+ } from "./chunk-JVO5GQZH.js";
32
28
  import {
33
29
  RawEventSampleEventTypes,
34
- aiUserFetchEventsHourly,
35
30
  auditLog,
36
31
  competitors,
37
- crawlerEventsHourly,
38
32
  createClient,
39
33
  gaAiReferrals,
40
34
  gaTrafficSnapshots,
@@ -44,15 +38,11 @@ import {
44
38
  querySnapshots,
45
39
  rawEventSamples,
46
40
  runs
47
- } from "./chunk-3UFQI4KL.js";
41
+ } from "./chunk-L5R5S57T.js";
48
42
  import {
49
- AgentTrustLevels,
50
43
  ProviderNames,
51
44
  RetrievalContracts,
52
45
  RunKinds,
53
- TrafficEventConfidences,
54
- TrafficEvidenceKinds,
55
- TrafficSourceTypes,
56
46
  computeCompetitorOverlap,
57
47
  countsAsMention,
58
48
  determineAnswerMentioned,
@@ -61,7 +51,7 @@ import {
61
51
  extractRecommendedCompetitors,
62
52
  normalizeUrlPath,
63
53
  openRouterRouteModel
64
- } from "./chunk-PHVIMUAQ.js";
54
+ } from "./chunk-KNKOTLVW.js";
65
55
 
66
56
  // src/commands/backfill.ts
67
57
  import { setImmediate as yieldToEventLoop } from "timers/promises";
@@ -439,7 +429,7 @@ No DB writes performed. Re-run without --dry-run to apply.`);
439
429
  }
440
430
  }
441
431
  async function backfillInsightsCommand(project, opts) {
442
- const { IntelligenceService } = await import("./intelligence-service-AMXDCTS2.js");
432
+ const { IntelligenceService } = await import("./intelligence-service-YJFZ6IBI.js");
443
433
  const config = loadConfig();
444
434
  const db = createClient(config.database);
445
435
  migrate(db);
@@ -799,163 +789,34 @@ async function backfillTrafficClassificationCommand(opts) {
799
789
  if (!isJson) {
800
790
  const mode = isDryRun ? " [DRY RUN \u2014 no writes]" : "";
801
791
  const scope = projectFilter ? `"${projectFilter}"` : "all projects";
802
- process.stderr.write(`Re-classifying unknown traffic samples for ${scope}${mode}...
792
+ process.stderr.write(`Re-classifying stored unknown traffic for ${scope}${mode}...
803
793
  `);
804
794
  }
805
795
  const projectIds = scopedProjects.map((p) => p.id);
806
- const result = {
807
- project: projectFilter ?? null,
808
- examined: 0,
809
- reclassified: 0,
810
- unknownBefore: 0,
811
- unknownAfter: 0,
812
- dryRun: isDryRun,
813
- byBot: {}
814
- };
815
- const unknownCountRow = db.select({ n: sql`count(*)` }).from(rawEventSamples).where(and(
796
+ const countUnknown = () => Number(db.select({ n: sql`count(*)` }).from(rawEventSamples).where(and(
816
797
  eq(rawEventSamples.eventType, RawEventSampleEventTypes.unknown),
817
798
  inArray(rawEventSamples.projectId, projectIds)
818
- )).get();
819
- result.unknownBefore = Number(unknownCountRow?.n ?? 0);
820
- const unknownSamples = db.select({
821
- id: rawEventSamples.id,
822
- projectId: rawEventSamples.projectId,
823
- sourceId: rawEventSamples.sourceId,
824
- ts: rawEventSamples.ts,
825
- userAgent: rawEventSamples.userAgent,
826
- pathNormalized: rawEventSamples.pathNormalized,
827
- status: rawEventSamples.status
828
- }).from(rawEventSamples).where(and(
829
- eq(rawEventSamples.eventType, RawEventSampleEventTypes.unknown),
830
- inArray(rawEventSamples.projectId, projectIds)
831
- )).all();
832
- result.examined = unknownSamples.length;
833
- if (unknownSamples.length === 0) {
834
- result.unknownAfter = result.unknownBefore;
835
- emitTrafficClassificationReport(result, isJson);
836
- return;
837
- }
838
- const now = (/* @__PURE__ */ new Date()).toISOString();
839
- for (const snap of unknownSamples) {
840
- if (!snap.userAgent) continue;
841
- const probe = {
842
- sourceType: TrafficSourceTypes["cloud-run"],
843
- evidenceKind: TrafficEvidenceKinds["raw-request"],
844
- confidence: TrafficEventConfidences.observed,
845
- eventId: snap.id,
846
- observedAt: snap.ts,
847
- method: "GET",
848
- requestUrl: `https://placeholder${snap.pathNormalized}`,
849
- host: "placeholder",
850
- path: snap.pathNormalized,
851
- queryString: null,
852
- status: snap.status ?? 200,
853
- userAgent: snap.userAgent,
854
- remoteIp: null,
855
- referer: null,
856
- latencyMs: null,
857
- requestSizeBytes: null,
858
- responseSizeBytes: null,
859
- providerResource: { type: "cloud_run_revision", labels: {} },
860
- providerLabels: {}
861
- };
862
- const userFetch = classifyAiUserFetch(probe);
863
- const classified = userFetch ?? classifyCrawler(probe);
864
- if (!classified) continue;
865
- result.reclassified++;
866
- result.byBot[classified.botId] = (result.byBot[classified.botId] ?? 0) + 1;
867
- if (isDryRun) continue;
868
- const tsHour = new Date(snap.ts);
869
- tsHour.setUTCMinutes(0, 0, 0);
870
- const tsHourIso = tsHour.toISOString();
871
- const status = snap.status ?? 200;
872
- db.transaction((tx) => {
873
- tx.update(rawEventSamples).set({
874
- eventType: userFetch ? RawEventSampleEventTypes.aiUserFetch : RawEventSampleEventTypes.crawler,
875
- classifierDetailsJson: {
876
- crawler: userFetch ? null : { ...classified, verificationManifest: null },
877
- aiUserFetch: userFetch ? { ...userFetch, verificationManifest: null } : null,
878
- aiReferral: null
879
- }
880
- }).where(eq(rawEventSamples.id, snap.id)).run();
881
- if (userFetch?.trust === AgentTrustLevels.likely_fake) {
882
- addLikelyFakeAgentHits(tx, {
883
- projectId: snap.projectId,
884
- sourceId: snap.sourceId,
885
- buckets: [{ tsHour: tsHourIso, botId: userFetch.botId, operator: userFetch.operator, reason: userFetch.trustReasons[0], hits: 1 }],
886
- now
887
- });
888
- } else if (userFetch) {
889
- tx.insert(aiUserFetchEventsHourly).values({
890
- projectId: snap.projectId,
891
- sourceId: snap.sourceId,
892
- tsHour: tsHourIso,
893
- botId: userFetch.botId,
894
- operator: userFetch.operator,
895
- verificationStatus: userFetch.verificationStatus,
896
- pathNormalized: snap.pathNormalized,
897
- status,
898
- hits: 1,
899
- sampledUserAgent: snap.userAgent,
900
- createdAt: now,
901
- updatedAt: now
902
- }).onConflictDoUpdate({
903
- target: [
904
- aiUserFetchEventsHourly.projectId,
905
- aiUserFetchEventsHourly.sourceId,
906
- aiUserFetchEventsHourly.tsHour,
907
- aiUserFetchEventsHourly.botId,
908
- aiUserFetchEventsHourly.verificationStatus,
909
- aiUserFetchEventsHourly.pathNormalized,
910
- aiUserFetchEventsHourly.status
911
- ],
912
- set: {
913
- hits: sql`${aiUserFetchEventsHourly.hits} + 1`,
914
- updatedAt: now
915
- }
916
- }).run();
917
- } else {
918
- tx.insert(crawlerEventsHourly).values({
919
- projectId: snap.projectId,
920
- sourceId: snap.sourceId,
921
- tsHour: tsHourIso,
922
- botId: classified.botId,
923
- operator: classified.operator,
924
- verificationStatus: classified.verificationStatus,
925
- pathNormalized: snap.pathNormalized,
926
- status,
927
- hits: 1,
928
- sampledUserAgent: snap.userAgent,
929
- createdAt: now,
930
- updatedAt: now
931
- }).onConflictDoUpdate({
932
- target: [
933
- crawlerEventsHourly.projectId,
934
- crawlerEventsHourly.sourceId,
935
- crawlerEventsHourly.tsHour,
936
- crawlerEventsHourly.botId,
937
- crawlerEventsHourly.verificationStatus,
938
- crawlerEventsHourly.pathNormalized,
939
- crawlerEventsHourly.status
940
- ],
941
- set: {
942
- hits: sql`${crawlerEventsHourly.hits} + 1`,
943
- updatedAt: now
944
- }
945
- }).run();
946
- }
947
- });
948
- }
949
- if (!isDryRun) {
950
- const afterRow = db.select({ n: sql`count(*)` }).from(rawEventSamples).where(and(
951
- eq(rawEventSamples.eventType, RawEventSampleEventTypes.unknown),
952
- inArray(rawEventSamples.projectId, projectIds)
953
- )).get();
954
- result.unknownAfter = Number(afterRow?.n ?? 0);
955
- } else {
956
- result.unknownAfter = result.unknownBefore - result.reclassified;
957
- }
958
- emitTrafficClassificationReport(result, isJson);
799
+ )).get()?.n ?? 0);
800
+ const unknownBefore = countUnknown();
801
+ const stored = await reclassifyStoredTraffic(db, { projectIds, dryRun: isDryRun });
802
+ const byBot = { ...stored.samples.byBot };
803
+ for (const [bot, hits] of Object.entries(stored.unrecognized.byBot)) byBot[bot] = (byBot[bot] ?? 0) + hits;
804
+ emitTrafficClassificationReport({
805
+ project: projectFilter ?? null,
806
+ examined: stored.samples.examined,
807
+ reclassified: stored.samples.reclassified,
808
+ unknownBefore,
809
+ unknownAfter: isDryRun ? unknownBefore - stored.samples.reclassified - stored.samples.removed : countUnknown(),
810
+ samplesCounted: stored.samples.counted,
811
+ samplesRemoved: stored.samples.removed,
812
+ dryRun: isDryRun,
813
+ byBot,
814
+ unrecognized: stored.unrecognized,
815
+ agentHits: stored.agentHits,
816
+ agentRequests: stored.agentRequests,
817
+ journeys: stored.journeys,
818
+ journeyMerges: stored.journeyMerges
819
+ }, isJson);
959
820
  }
960
821
  function emitTrafficClassificationReport(result, isJson) {
961
822
  if (isJson) {
@@ -969,7 +830,12 @@ Traffic classification ${result.dryRun ? "preview" : "recovery"} complete.`);
969
830
  console.log(` ${verb}: ${result.reclassified}`);
970
831
  console.log(` Unknown before: ${result.unknownBefore}`);
971
832
  console.log(` Unknown after: ${result.unknownAfter}`);
972
- if (result.reclassified > 0) {
833
+ console.log(` Unrecognized rows: ${result.unrecognized.examined} examined, ${result.unrecognized.moved} moved to a bot (${result.unrecognized.movedHits} hits), ${result.unrecognized.renamed} renamed, ${result.unrecognized.removed} removed`);
834
+ console.log(` Fake agent hits: ${result.agentHits.moved} hourly rows moved to likely fake (${result.agentHits.movedHits} hits)`);
835
+ console.log(` Agent requests: ${result.agentRequests.removed} removed (${result.agentRequests.probes} asked for a scanner path)`);
836
+ console.log(` Journeys: ${result.journeys.visitorsRemoved} visitors and ${result.journeys.visitsRemoved} visits removed, ${result.journeys.visitsRelanded} visits now start at a different page`);
837
+ console.log(` Split visitors: ${result.journeyMerges.visitorsMerged} joined to the same person's first visitor, seen from another IP (${result.journeyMerges.visitsJoined} visits merged)`);
838
+ if (Object.keys(result.byBot).length > 0) {
973
839
  console.log(` By bot:`);
974
840
  const sorted = Object.entries(result.byBot).sort(([, a], [, b]) => b - a);
975
841
  for (const [bot, count] of sorted) {
@@ -18827,7 +18827,9 @@ var agentTrustReasonSchema = z57.enum([
18827
18827
  /** The operator publishes a full user-agent string and this one differs from it. */
18828
18828
  "unusual-user-agent",
18829
18829
  /** The path asks for secrets, version-control data, admin logins or traverses directories. */
18830
- "scanner-path"
18830
+ "scanner-path",
18831
+ /** The same client (one IP) asked for scanner paths within a few minutes of this request. */
18832
+ "scanner-burst"
18831
18833
  ]);
18832
18834
  var AgentTrustReasons = agentTrustReasonSchema.enum;
18833
18835
  var trafficVerificationManifestSchema = z57.object({
@@ -25423,9 +25425,10 @@ var DOWNLOAD_EXTENSIONS = /* @__PURE__ */ new Set([
25423
25425
  "sql"
25424
25426
  ]);
25425
25427
  var SITEMAP_BASENAME = /^sitemap(?:[-_]index)?$/;
25428
+ var UNRECORDED_TRAFFIC_PATH = "(path not recorded)";
25426
25429
  function classifyTrafficPath(pathNormalized) {
25427
25430
  const raw = (pathNormalized ?? "").trim();
25428
- if (!raw) return TrafficPathClasses.other;
25431
+ if (!raw || raw === UNRECORDED_TRAFFIC_PATH) return TrafficPathClasses.other;
25429
25432
  const rawPath = raw.split(/[?#]/)[0] ?? "";
25430
25433
  const pathOnly = rawPath.length > 1 ? rawPath.replace(/\/+$/, "") || "/" : rawPath;
25431
25434
  if (!pathOnly) return TrafficPathClasses.other;
@@ -27888,6 +27891,7 @@ export {
27888
27891
  agentJourneysResponseSchema,
27889
27892
  agentJourneyDetailResponseSchema,
27890
27893
  TrafficPathClasses,
27894
+ UNRECORDED_TRAFFIC_PATH,
27891
27895
  classifyTrafficPath,
27892
27896
  segmentCrawlerHits,
27893
27897
  sumInfraHits,
@@ -20,7 +20,7 @@ import {
20
20
  templateLinkRatio,
21
21
  templateLinkUbiquityAvailable,
22
22
  validationError
23
- } from "./chunk-PHVIMUAQ.js";
23
+ } from "./chunk-KNKOTLVW.js";
24
24
  import {
25
25
  __export
26
26
  } from "./chunk-MLKGABMK.js";
@@ -47,6 +47,7 @@ __export(schema_exports, {
47
47
  agentJourneyCaptureDays: () => agentJourneyCaptureDays,
48
48
  agentJourneyEvents: () => agentJourneyEvents,
49
49
  agentMemory: () => agentMemory,
50
+ agentScannerClients: () => agentScannerClients,
50
51
  agentSessions: () => agentSessions,
51
52
  agentToolEvents: () => agentToolEvents,
52
53
  aiReferralEventsHourly: () => aiReferralEventsHourly,
@@ -112,6 +113,7 @@ __export(schema_exports, {
112
113
  insightNotifyState: () => insightNotifyState,
113
114
  insights: () => insights,
114
115
  journeyEvents: () => journeyEvents,
116
+ journeyVisitorAliases: () => journeyVisitorAliases,
115
117
  journeyVisitors: () => journeyVisitors,
116
118
  journeyVisits: () => journeyVisits,
117
119
  llmUsageEvents: () => llmUsageEvents,
@@ -176,6 +178,7 @@ __export(schema_exports, {
176
178
  siteCrawlSnapshots: () => siteCrawlSnapshots,
177
179
  siteLivenessState: () => siteLivenessState,
178
180
  trafficEventReceipts: () => trafficEventReceipts,
181
+ trafficReclassificationState: () => trafficReclassificationState,
179
182
  trafficSources: () => trafficSources,
180
183
  unrecognizedAgentEventsHourly: () => unrecognizedAgentEventsHourly,
181
184
  unrecognizedAgentNotifyState: () => unrecognizedAgentNotifyState,
@@ -2596,6 +2599,12 @@ var unrecognizedAgentNotifyState = sqliteTable2("unrecognized_agent_notify_state
2596
2599
  }, (table) => [
2597
2600
  primaryKey2({ columns: [table.projectId, table.agentName] })
2598
2601
  ]);
2602
+ var trafficReclassificationState = sqliteTable2("traffic_reclassification_state", {
2603
+ id: text2("id").primaryKey(),
2604
+ fingerprint: text2("fingerprint").notNull(),
2605
+ completedAt: text2("completed_at").notNull(),
2606
+ resultJson: text2("result_json", { mode: "json" }).$type()
2607
+ });
2599
2608
  var aiReferralEventsHourly = sqliteTable2("ai_referral_events_hourly", {
2600
2609
  projectId: text2("project_id").notNull().references(() => projects.id, { onDelete: "cascade" }),
2601
2610
  sourceId: text2("source_id").notNull().references(() => trafficSources.id, { onDelete: "cascade" }),
@@ -2680,6 +2689,15 @@ var journeyVisitors = sqliteTable2("journey_visitors", {
2680
2689
  index2("idx_journey_visitors_project_first_ai").on(table.projectId, table.firstAiAt),
2681
2690
  index2("idx_journey_visitors_last_seen").on(table.lastSeenAt)
2682
2691
  ]);
2692
+ var journeyVisitorAliases = sqliteTable2("journey_visitor_aliases", {
2693
+ projectId: text2("project_id").notNull().references(() => projects.id, { onDelete: "cascade" }),
2694
+ aliasKey: text2("alias_key").notNull(),
2695
+ visitorKey: text2("visitor_key").notNull(),
2696
+ createdAt: text2("created_at").notNull()
2697
+ }, (table) => [
2698
+ primaryKey2({ columns: [table.projectId, table.aliasKey] }),
2699
+ index2("idx_journey_visitor_aliases_visitor").on(table.projectId, table.visitorKey)
2700
+ ]);
2683
2701
  var journeyVisits = sqliteTable2("journey_visits", {
2684
2702
  id: text2("id").primaryKey(),
2685
2703
  projectId: text2("project_id").notNull().references(() => projects.id, { onDelete: "cascade" }),
@@ -2757,6 +2775,17 @@ var agentJourneyCaptureDays = sqliteTable2("agent_journey_capture_days", {
2757
2775
  primaryKey2({ columns: [table.projectId, table.sourceId, table.day] }),
2758
2776
  index2("idx_agent_journey_capture_days_day").on(table.day)
2759
2777
  ]);
2778
+ var agentScannerClients = sqliteTable2("agent_scanner_clients", {
2779
+ projectId: text2("project_id").notNull().references(() => projects.id, { onDelete: "cascade" }),
2780
+ sourceId: text2("source_id").notNull().references(() => trafficSources.id, { onDelete: "cascade" }),
2781
+ clientKey: text2("client_key").notNull(),
2782
+ firstProbeAt: text2("first_probe_at").notNull(),
2783
+ lastProbeAt: text2("last_probe_at").notNull(),
2784
+ updatedAt: text2("updated_at").notNull()
2785
+ }, (table) => [
2786
+ primaryKey2({ columns: [table.projectId, table.sourceId, table.clientKey] }),
2787
+ index2("idx_agent_scanner_clients_source_last").on(table.sourceId, table.lastProbeAt)
2788
+ ]);
2760
2789
  var discoverySessions = sqliteTable2("discovery_sessions", {
2761
2790
  id: text2("id").primaryKey(),
2762
2791
  projectId: text2("project_id").notNull().references(() => projects.id, { onDelete: "cascade" }),
@@ -8538,6 +8567,48 @@ var MIGRATION_VERSIONS = [
8538
8567
  `CREATE INDEX IF NOT EXISTS idx_ai_user_fetch_likely_fake_project_ts ON ai_user_fetch_likely_fake_hourly(project_id, ts_hour)`,
8539
8568
  `CREATE INDEX IF NOT EXISTS idx_ai_user_fetch_likely_fake_source_ts ON ai_user_fetch_likely_fake_hourly(source_id, ts_hour)`
8540
8569
  ]
8570
+ },
8571
+ {
8572
+ version: 204,
8573
+ name: "traffic-reclassification-state",
8574
+ statements: [
8575
+ `CREATE TABLE IF NOT EXISTS traffic_reclassification_state (
8576
+ id TEXT PRIMARY KEY,
8577
+ fingerprint TEXT NOT NULL,
8578
+ completed_at TEXT NOT NULL,
8579
+ result_json TEXT
8580
+ )`
8581
+ ]
8582
+ },
8583
+ {
8584
+ version: 205,
8585
+ name: "agent-scanner-clients",
8586
+ statements: [
8587
+ `CREATE TABLE IF NOT EXISTS agent_scanner_clients (
8588
+ project_id TEXT NOT NULL REFERENCES projects(id) ON DELETE CASCADE,
8589
+ source_id TEXT NOT NULL REFERENCES traffic_sources(id) ON DELETE CASCADE,
8590
+ client_key TEXT NOT NULL,
8591
+ first_probe_at TEXT NOT NULL,
8592
+ last_probe_at TEXT NOT NULL,
8593
+ updated_at TEXT NOT NULL,
8594
+ PRIMARY KEY (project_id, source_id, client_key)
8595
+ )`,
8596
+ `CREATE INDEX IF NOT EXISTS idx_agent_scanner_clients_source_last ON agent_scanner_clients(source_id, last_probe_at)`
8597
+ ]
8598
+ },
8599
+ {
8600
+ version: 206,
8601
+ name: "journey-visitor-aliases",
8602
+ statements: [
8603
+ `CREATE TABLE IF NOT EXISTS journey_visitor_aliases (
8604
+ project_id TEXT NOT NULL REFERENCES projects(id) ON DELETE CASCADE,
8605
+ alias_key TEXT NOT NULL,
8606
+ visitor_key TEXT NOT NULL,
8607
+ created_at TEXT NOT NULL,
8608
+ PRIMARY KEY (project_id, alias_key)
8609
+ )`,
8610
+ `CREATE INDEX IF NOT EXISTS idx_journey_visitor_aliases_visitor ON journey_visitor_aliases(project_id, visitor_key)`
8611
+ ]
8541
8612
  }
8542
8613
  ];
8543
8614
  var AERO_LEDGER_REBUILDS = [
@@ -10046,14 +10117,17 @@ export {
10046
10117
  aiUserFetchVerificationManifestsHourly,
10047
10118
  unrecognizedAgentEventsHourly,
10048
10119
  unrecognizedAgentNotifyState,
10120
+ trafficReclassificationState,
10049
10121
  aiReferralEventsHourly,
10050
10122
  rawEventSamples,
10051
10123
  RawEventSampleEventTypes,
10052
10124
  journeyVisitors,
10125
+ journeyVisitorAliases,
10053
10126
  journeyVisits,
10054
10127
  journeyEvents,
10055
10128
  agentJourneyEvents,
10056
10129
  agentJourneyCaptureDays,
10130
+ agentScannerClients,
10057
10131
  discoverySessions,
10058
10132
  researchRuns,
10059
10133
  researchRunQueries,
@@ -7,12 +7,12 @@ import {
7
7
  import {
8
8
  createApiClient,
9
9
  runWithUsageTags
10
- } from "./chunk-IPPNN5KE.js";
10
+ } from "./chunk-UMV4HYHD.js";
11
11
  import {
12
12
  canonryMcpTools,
13
13
  mcpOutputSchema,
14
14
  toolOperationAccess
15
- } from "./chunk-HIC62JTS.js";
15
+ } from "./chunk-Q7354YI3.js";
16
16
  import {
17
17
  PACKAGE_VERSION
18
18
  } from "./chunk-AOJU5LKX.js";
@@ -25,7 +25,7 @@ import {
25
25
  isReadOnlyKey,
26
26
  restrictedWriteScopes,
27
27
  upgradeCaveatFor
28
- } from "./chunk-PHVIMUAQ.js";
28
+ } from "./chunk-KNKOTLVW.js";
29
29
 
30
30
  // src/mcp/server.ts
31
31
  import { randomUUID } from "crypto";
@@ -4,7 +4,7 @@ import {
4
4
  } from "./chunk-HGMYEDAQ.js";
5
5
  import {
6
6
  describeError
7
- } from "./chunk-PHVIMUAQ.js";
7
+ } from "./chunk-KNKOTLVW.js";
8
8
 
9
9
  // src/gsc-sitemap-submission.ts
10
10
  function dedupeGscSitemapUrls(urls) {
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  createApiClient
3
- } from "./chunk-IPPNN5KE.js";
3
+ } from "./chunk-UMV4HYHD.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-PHVIMUAQ.js";
22
+ } from "./chunk-KNKOTLVW.js";
23
23
 
24
24
  // src/commands/run.ts
25
25
  function getClient() {
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  API_PROVIDER_NAMES,
3
3
  ProviderNames
4
- } from "./chunk-PHVIMUAQ.js";
4
+ } from "./chunk-KNKOTLVW.js";
5
5
 
6
6
  // src/provider-registration.ts
7
7
  function isApiProviderRegistrable(name, entry) {
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  USAGE_TELEMETRY_HEADERS,
3
3
  redactLogString
4
- } from "./chunk-PHVIMUAQ.js";
4
+ } from "./chunk-KNKOTLVW.js";
5
5
 
6
6
  // ../api-routes/src/request-context.ts
7
7
  import { AsyncLocalStorage } from "async_hooks";
@@ -2,11 +2,11 @@ import {
2
2
  dedupeGscSitemapUrls,
3
3
  resolveDiscoveredGscSitemapUrls,
4
4
  submitGscSitemapBatches
5
- } from "./chunk-W5ZBMBBZ.js";
5
+ } from "./chunk-OHDSI5XS.js";
6
6
  import {
7
7
  measurementDraftOperationSchema,
8
8
  runMeasurementDraftAction
9
- } from "./chunk-KFMU6CLU.js";
9
+ } from "./chunk-QEATYB7C.js";
10
10
  import {
11
11
  CliError
12
12
  } from "./chunk-HGMYEDAQ.js";
@@ -184,7 +184,7 @@ import {
184
184
  trafficUnrecognizedAgentsQuerySchema,
185
185
  visibilityCompareSelectionSchema,
186
186
  visibilityReportRequestSchema
187
- } from "./chunk-PHVIMUAQ.js";
187
+ } from "./chunk-KNKOTLVW.js";
188
188
 
189
189
  // src/mcp/tool-registry.ts
190
190
  import { z as z2 } from "zod";
@@ -23,7 +23,7 @@ import {
23
23
  measurementDraftUpsertGroupRequestSchema,
24
24
  measurementDraftUpsertMarketRequestSchema,
25
25
  measurementDraftUpsertTargetRequestSchema
26
- } from "./chunk-PHVIMUAQ.js";
26
+ } from "./chunk-KNKOTLVW.js";
27
27
 
28
28
  // src/measurement-draft-actions.ts
29
29
  import { z } from "zod";
@@ -5,7 +5,7 @@ import {
5
5
  siteCrawlGraphNodes,
6
6
  siteCrawlPages,
7
7
  siteCrawlSnapshots
8
- } from "./chunk-3UFQI4KL.js";
8
+ } from "./chunk-L5R5S57T.js";
9
9
  import {
10
10
  SITE_CRAWL_GRAPH_MAX_EDGES,
11
11
  SITE_CRAWL_GRAPH_MAX_NODES,
@@ -15,7 +15,7 @@ import {
15
15
  factorStatusFromDistribution,
16
16
  factorStatusFromScore,
17
17
  roundPreservingTotal
18
- } from "./chunk-PHVIMUAQ.js";
18
+ } from "./chunk-KNKOTLVW.js";
19
19
 
20
20
  // src/site-audit-factors.ts
21
21
  function recordedSharePct(factor) {
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  hostMatchesDomain
3
- } from "./chunk-PHVIMUAQ.js";
3
+ } from "./chunk-KNKOTLVW.js";
4
4
 
5
5
  // src/citation-utils.ts
6
6
  function pickProjectCitedDomain(citedDomains, projectDomains) {
@@ -1,9 +1,9 @@
1
1
  import {
2
2
  trackIntegrationConnection
3
- } from "./chunk-P76XOEWL.js";
3
+ } from "./chunk-ZXMDIWW6.js";
4
4
  import {
5
5
  cliRuntimeContext
6
- } from "./chunk-YJOGWS7F.js";
6
+ } from "./chunk-X7XKMARG.js";
7
7
 
8
8
  // src/cli-connection-telemetry.ts
9
9
  function trackCliConnection(properties) {
@@ -5,7 +5,7 @@ import {
5
5
  isStoredPageReadTool,
6
6
  isStoredReadTool,
7
7
  truncateToolResult
8
- } from "./chunk-4D2QHIRS.js";
8
+ } from "./chunk-UMEQ7EYN.js";
9
9
  import {
10
10
  CANONRY_MCP_TOOLKITS,
11
11
  resolveAeroSkillDir
@@ -23,18 +23,18 @@ import {
23
23
  resolveApiKeyFor,
24
24
  resolveModelForProvider,
25
25
  validateAgentProviderRegistry
26
- } from "./chunk-WA4FD5Y6.js";
26
+ } from "./chunk-DWK6NIJF.js";
27
27
  import {
28
28
  CanonryMcpToolNames,
29
29
  canonryMcpTools
30
- } from "./chunk-HIC62JTS.js";
30
+ } from "./chunk-Q7354YI3.js";
31
31
  import {
32
32
  createLogger
33
- } from "./chunk-SVMTN7MI.js";
33
+ } from "./chunk-6SGHSSWQ.js";
34
34
  import {
35
35
  agentToolEvents,
36
36
  llmUsageEvents
37
- } from "./chunk-3UFQI4KL.js";
37
+ } from "./chunk-L5R5S57T.js";
38
38
  import {
39
39
  MeasurementPortfolioLists,
40
40
  SeoCapabilities,
@@ -43,7 +43,7 @@ import {
43
43
  describeError,
44
44
  validationError,
45
45
  visibilityReportRequestSchema
46
- } from "./chunk-PHVIMUAQ.js";
46
+ } from "./chunk-KNKOTLVW.js";
47
47
 
48
48
  // src/agent/session.ts
49
49
  import fs2 from "fs";
@@ -1,16 +1,16 @@
1
1
  import {
2
2
  runWithUsageTags
3
- } from "./chunk-IPPNN5KE.js";
3
+ } from "./chunk-UMV4HYHD.js";
4
4
  import {
5
5
  CanonryMcpToolNames,
6
6
  canonryMcpTools
7
- } from "./chunk-HIC62JTS.js";
7
+ } from "./chunk-Q7354YI3.js";
8
8
  import {
9
9
  CliError
10
10
  } from "./chunk-HGMYEDAQ.js";
11
11
  import {
12
12
  buildOpenApiDocument
13
- } from "./chunk-5AGYH5PX.js";
13
+ } from "./chunk-JVO5GQZH.js";
14
14
  import {
15
15
  DEFAULT_COMPETITOR_AUTO_ALIAS_MODE,
16
16
  MeasurementPortfolioLists,
@@ -23,7 +23,7 @@ import {
23
23
  seoDatasetWithoutVendor,
24
24
  seoProviderSchema,
25
25
  truncateUtf16
26
- } from "./chunk-PHVIMUAQ.js";
26
+ } from "./chunk-KNKOTLVW.js";
27
27
 
28
28
  // src/agent/tools.ts
29
29
  import { Type as Type2 } from "@earendil-works/pi-ai";