@ainyc/canonry 4.114.1 → 4.115.1

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 (25) hide show
  1. package/assets/assets/{BacklinksPage-C60ma4Sg.js → BacklinksPage-yUb8oJuq.js} +1 -1
  2. package/assets/assets/{ChartPrimitives-Blgw1l6J.js → ChartPrimitives-CdQM3YDG.js} +1 -1
  3. package/assets/assets/ProjectPage-CHj9fvTs.js +7 -0
  4. package/assets/assets/{RunRow-DgQiXWZl.js → RunRow-BU_x7EcP.js} +1 -1
  5. package/assets/assets/{RunsPage-C9upHccV.js → RunsPage-CFIBWaO7.js} +1 -1
  6. package/assets/assets/{SettingsPage-Bz_-_DnJ.js → SettingsPage-PyMryUad.js} +1 -1
  7. package/assets/assets/{TrafficPage-BhBnQl2N.js → TrafficPage-471ypAdQ.js} +1 -1
  8. package/assets/assets/{TrafficSourceDetailPage-DWXqcRNO.js → TrafficSourceDetailPage-CI7TEQge.js} +1 -1
  9. package/assets/assets/{arrow-left-C6SuuEtD.js → arrow-left-D2N9u-0i.js} +1 -1
  10. package/assets/assets/{extract-error-message-DPZ5yqzd.js → extract-error-message-CAdsqKp3.js} +1 -1
  11. package/assets/assets/index-B4R1-8hR.css +1 -0
  12. package/assets/assets/{index-C3oQZHf8.js → index-CoL5HENE.js} +66 -66
  13. package/assets/assets/{trash-2-D3Nju7AK.js → trash-2-UgQrN5Np.js} +1 -1
  14. package/assets/index.html +2 -2
  15. package/dist/{chunk-VEUBAZRG.js → chunk-6LOKMEL3.js} +101 -0
  16. package/dist/{chunk-WMWZW34J.js → chunk-B2SNXXAJ.js} +4 -4
  17. package/dist/{chunk-DUBZH5JW.js → chunk-CW4JISBL.js} +1 -1
  18. package/dist/{chunk-3VSTTH4M.js → chunk-Z3OGDQHB.js} +489 -244
  19. package/dist/cli.js +52 -8
  20. package/dist/index.js +4 -4
  21. package/dist/{intelligence-service-I5EQ77KZ.js → intelligence-service-4AWB2V7U.js} +2 -2
  22. package/dist/mcp.js +2 -2
  23. package/package.json +8 -8
  24. package/assets/assets/ProjectPage-DfvEEwNU.js +0 -7
  25. package/assets/assets/index-CReX5Jn9.css +0 -1
@@ -1 +1 @@
1
- import{c}from"./index-C3oQZHf8.js";const a=[["circle",{cx:"12",cy:"12",r:"10",key:"1mglay"}],["path",{d:"m9 12 2 2 4-4",key:"dzmm74"}]],h=c("circle-check",a);const e=[["circle",{cx:"12",cy:"12",r:"10",key:"1mglay"}],["path",{d:"M9.09 9a3 3 0 0 1 5.83 1c0 2-3 3-3 3",key:"1u773s"}],["path",{d:"M12 17h.01",key:"p32p05"}]],n=c("circle-question-mark",e);const o=[["path",{d:"M12 15V3",key:"m9g1x1"}],["path",{d:"M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4",key:"ih7n3h"}],["path",{d:"m7 10 5 5 5-5",key:"brsn70"}]],s=c("download",o);const t=[["path",{d:"M10 11v6",key:"nco0om"}],["path",{d:"M14 11v6",key:"outv1u"}],["path",{d:"M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6",key:"miytrc"}],["path",{d:"M3 6h18",key:"d0wm0j"}],["path",{d:"M8 6V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2",key:"e791ji"}]],r=c("trash-2",t);export{h as C,s as D,r as T,n as a};
1
+ import{c}from"./index-CoL5HENE.js";const a=[["circle",{cx:"12",cy:"12",r:"10",key:"1mglay"}],["path",{d:"m9 12 2 2 4-4",key:"dzmm74"}]],h=c("circle-check",a);const e=[["circle",{cx:"12",cy:"12",r:"10",key:"1mglay"}],["path",{d:"M9.09 9a3 3 0 0 1 5.83 1c0 2-3 3-3 3",key:"1u773s"}],["path",{d:"M12 17h.01",key:"p32p05"}]],n=c("circle-question-mark",e);const o=[["path",{d:"M12 15V3",key:"m9g1x1"}],["path",{d:"M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4",key:"ih7n3h"}],["path",{d:"m7 10 5 5 5-5",key:"brsn70"}]],s=c("download",o);const t=[["path",{d:"M10 11v6",key:"nco0om"}],["path",{d:"M14 11v6",key:"outv1u"}],["path",{d:"M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6",key:"miytrc"}],["path",{d:"M3 6h18",key:"d0wm0j"}],["path",{d:"M8 6V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2",key:"e791ji"}]],r=c("trash-2",t);export{h as C,s as D,r as T,n as a};
package/assets/index.html CHANGED
@@ -12,12 +12,12 @@
12
12
  <link rel="icon" type="image/png" sizes="32x32" href="./favicon-32.png" />
13
13
  <link rel="apple-touch-icon" href="./apple-touch-icon.png" />
14
14
  <title>Canonry</title>
15
- <script type="module" crossorigin src="./assets/index-C3oQZHf8.js"></script>
15
+ <script type="module" crossorigin src="./assets/index-CoL5HENE.js"></script>
16
16
  <link rel="modulepreload" crossorigin href="./assets/vendor-tanstack-Be8JdV5M.js">
17
17
  <link rel="modulepreload" crossorigin href="./assets/vendor-radix-CQ77EO2y.js">
18
18
  <link rel="modulepreload" crossorigin href="./assets/vendor-recharts-C9EZkgbP.js">
19
19
  <link rel="modulepreload" crossorigin href="./assets/vendor-markdown-6dwjPOKK.js">
20
- <link rel="stylesheet" crossorigin href="./assets/index-CReX5Jn9.css">
20
+ <link rel="stylesheet" crossorigin href="./assets/index-B4R1-8hR.css">
21
21
  </head>
22
22
  <body>
23
23
  <div id="root"></div>
@@ -2908,6 +2908,64 @@ function calendarMonthBounds(month) {
2908
2908
 
2909
2909
  // ../contracts/src/ga.ts
2910
2910
  import { z as z21 } from "zod";
2911
+ var ga4AiReferralTrafficClassSchema = z21.enum(["organic", "paid"]);
2912
+ var GA4AiReferralTrafficClasses = ga4AiReferralTrafficClassSchema.enum;
2913
+ var PAID_CHANNEL_GROUPS = /* @__PURE__ */ new Set([
2914
+ "paid search",
2915
+ "paid social",
2916
+ "paid shopping",
2917
+ "paid video",
2918
+ "paid other",
2919
+ "display",
2920
+ "cross-network"
2921
+ ]);
2922
+ var PAID_SOURCE_OR_MEDIUM_VALUES = /* @__PURE__ */ new Set([
2923
+ "ad",
2924
+ "ads",
2925
+ "cpa",
2926
+ "cpc",
2927
+ "cpm",
2928
+ "cpv",
2929
+ "display",
2930
+ "openai-ads",
2931
+ "openai_ads",
2932
+ "paid",
2933
+ "paid-ai",
2934
+ "paid_ai",
2935
+ "paidai",
2936
+ "ppc",
2937
+ "retargeting",
2938
+ "sponsored"
2939
+ ]);
2940
+ var PAID_QUERY_PARAMS = ["utm_medium", "utm_campaign", "utm_content", "utm_term"];
2941
+ function normalizedTokens(value) {
2942
+ return (value ?? "").toLowerCase().split(/[^a-z0-9]+/).filter(Boolean);
2943
+ }
2944
+ function hasPaidToken(value) {
2945
+ const normalized = (value ?? "").trim().toLowerCase();
2946
+ if (!normalized) return false;
2947
+ if (PAID_SOURCE_OR_MEDIUM_VALUES.has(normalized)) return true;
2948
+ return normalizedTokens(normalized).some((token) => PAID_SOURCE_OR_MEDIUM_VALUES.has(token));
2949
+ }
2950
+ function hasPaidLandingPageParam(landingPage) {
2951
+ if (!landingPage) return false;
2952
+ try {
2953
+ const url = new URL(landingPage, "https://canonry.local");
2954
+ return PAID_QUERY_PARAMS.some((key) => hasPaidToken(url.searchParams.get(key)));
2955
+ } catch {
2956
+ return false;
2957
+ }
2958
+ }
2959
+ function classifyGa4AiReferralTrafficClass(input) {
2960
+ const channelGroup = (input.channelGroup ?? "").trim().toLowerCase();
2961
+ if (PAID_CHANNEL_GROUPS.has(channelGroup) || channelGroup.startsWith("paid ")) {
2962
+ return GA4AiReferralTrafficClasses.paid;
2963
+ }
2964
+ if (hasPaidToken(input.medium) || hasPaidToken(input.source) || hasPaidLandingPageParam(input.landingPage)) {
2965
+ return GA4AiReferralTrafficClasses.paid;
2966
+ }
2967
+ return GA4AiReferralTrafficClasses.organic;
2968
+ }
2911
2969
  var ga4ConnectionDtoSchema = z21.object({
2912
2970
  id: z21.string(),
2913
2971
  projectId: z21.string(),
@@ -2928,6 +2986,7 @@ var ga4SourceDimensionSchema = z21.enum(["session", "first_user", "manual_utm"])
2928
2986
  var ga4AiReferralDtoSchema = z21.object({
2929
2987
  source: z21.string(),
2930
2988
  medium: z21.string(),
2989
+ trafficClass: ga4AiReferralTrafficClassSchema,
2931
2990
  sessions: z21.number(),
2932
2991
  users: z21.number(),
2933
2992
  /**
@@ -2942,6 +3001,7 @@ var ga4AiReferralDtoSchema = z21.object({
2942
3001
  var ga4AiReferralLandingPageDtoSchema = z21.object({
2943
3002
  source: z21.string(),
2944
3003
  medium: z21.string(),
3004
+ trafficClass: ga4AiReferralTrafficClassSchema,
2945
3005
  /**
2946
3006
  * The winning attribution dimension for this (source, medium, landingPage)
2947
3007
  * tuple — the one with the highest session count.
@@ -2991,10 +3051,26 @@ var ga4TrafficSummaryDtoSchema = z21.object({
2991
3051
  aiSessionsDeduped: z21.number(),
2992
3052
  /** Deduped AI user total: MAX(users) per date+source+medium across attribution dimensions, then summed. */
2993
3053
  aiUsersDeduped: z21.number(),
3054
+ /** Deduped AI sessions whose attribution carries paid intent. */
3055
+ paidAiSessionsDeduped: z21.number(),
3056
+ /** Deduped users for paid AI sessions. */
3057
+ paidAiUsersDeduped: z21.number(),
3058
+ /** Deduped AI sessions without paid intent evidence. */
3059
+ organicAiSessionsDeduped: z21.number(),
3060
+ /** Deduped users for organic/non-paid AI sessions. */
3061
+ organicAiUsersDeduped: z21.number(),
2994
3062
  /** AI sessions whose CURRENT sessionSource matched an AI engine. Can overlap with raw Organic/Social/Direct totals; `channelBreakdown` removes those overlaps for display. */
2995
3063
  aiSessionsBySession: z21.number(),
2996
3064
  /** AI users whose CURRENT sessionSource matched an AI engine. Can overlap with raw Organic/Social/Direct totals. */
2997
3065
  aiUsersBySession: z21.number(),
3066
+ /** Session-source-only paid AI sessions. */
3067
+ paidAiSessionsBySession: z21.number(),
3068
+ /** Session-source-only paid AI users. */
3069
+ paidAiUsersBySession: z21.number(),
3070
+ /** Session-source-only organic/non-paid AI sessions. */
3071
+ organicAiSessionsBySession: z21.number(),
3072
+ /** Session-source-only organic/non-paid AI users. */
3073
+ organicAiUsersBySession: z21.number(),
2998
3074
  socialReferrals: z21.array(ga4SocialReferralDtoSchema),
2999
3075
  /** Total social sessions (session-scoped, no cross-dimension dedup needed). */
3000
3076
  socialSessions: z21.number(),
@@ -3008,6 +3084,14 @@ var ga4TrafficSummaryDtoSchema = z21.object({
3008
3084
  aiSharePct: z21.number(),
3009
3085
  /** Session-source-only AI sessions as a percentage of total sessions (0–100, rounded). Can overlap with raw Organic/Social/Direct totals. */
3010
3086
  aiSharePctBySession: z21.number(),
3087
+ /** Paid AI sessions as a percentage of total sessions (0–100, rounded). */
3088
+ paidAiSharePct: z21.number(),
3089
+ /** Session-source paid AI sessions as a percentage of total sessions (0–100, rounded). */
3090
+ paidAiSharePctBySession: z21.number(),
3091
+ /** Organic/non-paid AI sessions as a percentage of total sessions (0–100, rounded). */
3092
+ organicAiSharePct: z21.number(),
3093
+ /** Session-source organic/non-paid AI sessions as a percentage of total sessions (0–100, rounded). */
3094
+ organicAiSharePctBySession: z21.number(),
3011
3095
  /** Direct-channel sessions as a percentage of total sessions (0–100, rounded). */
3012
3096
  directSharePct: z21.number(),
3013
3097
  /** Social sessions as a percentage of total sessions (0–100, rounded). */
@@ -3018,6 +3102,14 @@ var ga4TrafficSummaryDtoSchema = z21.object({
3018
3102
  aiSharePctDisplay: z21.string(),
3019
3103
  /** Display string for aiSharePctBySession: 'X%', '<1%' for non-zero shares that round below 1, or '—' when sessions exist but total is unknown (partial sync). */
3020
3104
  aiSharePctBySessionDisplay: z21.string(),
3105
+ /** Display string for paidAiSharePct. */
3106
+ paidAiSharePctDisplay: z21.string(),
3107
+ /** Display string for paidAiSharePctBySession. */
3108
+ paidAiSharePctBySessionDisplay: z21.string(),
3109
+ /** Display string for organicAiSharePct. */
3110
+ organicAiSharePctDisplay: z21.string(),
3111
+ /** Display string for organicAiSharePctBySession. */
3112
+ organicAiSharePctBySessionDisplay: z21.string(),
3021
3113
  /** Display string for directSharePct: 'X%', '<1%' for non-zero shares that round below 1, or '—' when sessions exist but total is unknown (partial sync). */
3022
3114
  directSharePctDisplay: z21.string(),
3023
3115
  /** Display string for socialSharePct: 'X%', '<1%' for non-zero shares that round below 1, or '—' when sessions exist but total is unknown (partial sync). */
@@ -3057,6 +3149,7 @@ var ga4AiReferralHistoryEntrySchema = z21.object({
3057
3149
  date: z21.string(),
3058
3150
  source: z21.string(),
3059
3151
  medium: z21.string(),
3152
+ trafficClass: ga4AiReferralTrafficClassSchema,
3060
3153
  landingPage: z21.string(),
3061
3154
  sessions: z21.number(),
3062
3155
  users: z21.number(),
@@ -4373,10 +4466,16 @@ var socialReferralSectionSchema = z28.object({
4373
4466
  var aiReferralSectionSchema = z28.object({
4374
4467
  totalSessions: z28.number(),
4375
4468
  totalUsers: z28.number(),
4469
+ paidSessions: z28.number(),
4470
+ paidUsers: z28.number(),
4471
+ organicSessions: z28.number(),
4472
+ organicUsers: z28.number(),
4376
4473
  bySource: z28.array(z28.object({
4377
4474
  source: z28.string(),
4378
4475
  sessions: z28.number(),
4379
4476
  users: z28.number(),
4477
+ paidSessions: z28.number(),
4478
+ organicSessions: z28.number(),
4380
4479
  sharePct: z28.number()
4381
4480
  })),
4382
4481
  trend: z28.array(z28.object({ date: z28.string(), sessions: z28.number() })),
@@ -5836,6 +5935,8 @@ export {
5836
5935
  windowCutoff,
5837
5936
  visibilityStatsDtoSchema,
5838
5937
  calendarMonthBounds,
5938
+ GA4AiReferralTrafficClasses,
5939
+ classifyGa4AiReferralTrafficClass,
5839
5940
  ga4StatusDtoSchema,
5840
5941
  ga4SyncResponseDtoSchema,
5841
5942
  ga4AiReferralHistoryEntrySchema,
@@ -10,7 +10,7 @@ import {
10
10
  loadConfig,
11
11
  loadConfigRaw,
12
12
  saveConfigPatch
13
- } from "./chunk-DUBZH5JW.js";
13
+ } from "./chunk-CW4JISBL.js";
14
14
  import {
15
15
  CC_CACHE_DIR,
16
16
  DUCKDB_SPEC,
@@ -115,7 +115,7 @@ import {
115
115
  siteAuditPages,
116
116
  siteAuditSnapshots,
117
117
  usageCounters
118
- } from "./chunk-3VSTTH4M.js";
118
+ } from "./chunk-Z3OGDQHB.js";
119
119
  import {
120
120
  AGENT_MEMORY_VALUE_MAX_BYTES,
121
121
  AGENT_PROVIDER_IDS,
@@ -178,7 +178,7 @@ import {
178
178
  validationError,
179
179
  winnabilityClassLabel,
180
180
  withRetry
181
- } from "./chunk-VEUBAZRG.js";
181
+ } from "./chunk-6LOKMEL3.js";
182
182
 
183
183
  // src/telemetry.ts
184
184
  import crypto from "crypto";
@@ -6515,7 +6515,7 @@ function readStoredGroundingSources(rawResponse) {
6515
6515
  return result;
6516
6516
  }
6517
6517
  async function backfillInsightsCommand(project, opts) {
6518
- const { IntelligenceService: IntelligenceService2 } = await import("./intelligence-service-I5EQ77KZ.js");
6518
+ const { IntelligenceService: IntelligenceService2 } = await import("./intelligence-service-4AWB2V7U.js");
6519
6519
  const config = loadConfig();
6520
6520
  const db = createClient(config.database);
6521
6521
  migrate(db);
@@ -25,7 +25,7 @@ import {
25
25
  trafficConnectVercelRequestSchema,
26
26
  trafficConnectWordpressRequestSchema,
27
27
  trafficEventKindSchema
28
- } from "./chunk-VEUBAZRG.js";
28
+ } from "./chunk-6LOKMEL3.js";
29
29
 
30
30
  // src/config.ts
31
31
  import fs from "fs";