@canonry/canonry 4.172.2 → 4.172.3

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/{AuditHistoryPanel-DnqySUw3.js → AuditHistoryPanel-DF8utxHN.js} +1 -1
  2. package/assets/assets/{BacklinksPage-CbcHWD-G.js → BacklinksPage-Hz5fjTP-.js} +1 -1
  3. package/assets/assets/{HistoryPage-BYFSyxuB.js → HistoryPage-EeNWcnRk.js} +1 -1
  4. package/assets/assets/{MeasurementPropertyPage-BBnXQPIv.js → MeasurementPropertyPage-CWvVMiIo.js} +1 -1
  5. package/assets/assets/{ProjectPage-Cq5bHpmk.js → ProjectPage-CBVwd4DJ.js} +8 -8
  6. package/assets/assets/{RunRow-lfyHktTf.js → RunRow-CLwmqMWg.js} +1 -1
  7. package/assets/assets/{RunsPage-ngnP0Y_D.js → RunsPage-Cxc9xDm9.js} +1 -1
  8. package/assets/assets/{SettingsPage-DEg74T20.js → SettingsPage-gg7QM6am.js} +1 -1
  9. package/assets/assets/{SiteHealthSection-C6ycXwbt.js → SiteHealthSection-DhpNThBa.js} +3 -3
  10. package/assets/assets/{TrafficPage-hrJ1IDqA.js → TrafficPage-BkDwv0uO.js} +1 -1
  11. package/assets/assets/{TrafficSourceDetailPage-fu7nPl3E.js → TrafficSourceDetailPage-gyh7Kxb3.js} +1 -1
  12. package/assets/assets/{extract-error-message-dcdO9njP.js → extract-error-message-DVQ46FzX.js} +1 -1
  13. package/assets/assets/{index-DpQ_-QC_.js → index-ClNW_gZV.js} +19 -19
  14. package/assets/assets/{react-sigma_core.esm.min-DZGxGBSe.js → react-sigma_core.esm.min-BhFLGF9e.js} +1 -1
  15. package/assets/index.html +1 -1
  16. package/dist/{chunk-YXDCVM5U.js → chunk-BZDNTUCZ.js} +1 -1
  17. package/dist/{chunk-TI3SZAVI.js → chunk-OHSUOEVB.js} +4 -4
  18. package/dist/{chunk-U5JTZM66.js → chunk-WFVK3XC7.js} +2 -2
  19. package/dist/{chunk-EGGQSFQL.js → chunk-WGN2VT7L.js} +49 -1
  20. package/dist/{chunk-PXTSQ67Z.js → chunk-XEWBDO5L.js} +117 -5
  21. package/dist/cli.js +40 -5
  22. package/dist/index.js +4 -4
  23. package/dist/{intelligence-service-H7756PBD.js → intelligence-service-PPYG6NJP.js} +2 -2
  24. package/dist/mcp.js +3 -3
  25. package/package.json +11 -11
@@ -1,4 +1,4 @@
1
- import{g as Bt,t as S,r as C}from"./vendor-tanstack-Dock0eH1.js";import{e as Ht,G as Wt}from"./SiteHealthSection-C6ycXwbt.js";import"./index-DpQ_-QC_.js";import"./vendor-radix-4UOaVWza.js";import"./vendor-recharts-D8rt5lKn.js";import"./vendor-lucide-nYKv-BB7.js";import"./vendor-markdown-Bn7fRwrx.js";import"./vendor-yaml-GWJz5H2G.js";import"./ChartPrimitives-BoYe2M-i.js";function Vt(r,n){if(typeof r!="object"||!r)return r;var i=r[Symbol.toPrimitive];if(i!==void 0){var e=i.call(r,n);if(typeof e!="object")return e;throw new TypeError("@@toPrimitive must return a primitive value.")}return String(r)}function ae(r){var n=Vt(r,"string");return typeof n=="symbol"?n:n+""}function A(r,n){if(!(r instanceof n))throw new TypeError("Cannot call a class as a function")}function He(r,n){for(var i=0;i<n.length;i++){var e=n[i];e.enumerable=e.enumerable||!1,e.configurable=!0,"value"in e&&(e.writable=!0),Object.defineProperty(r,ae(e.key),e)}}function L(r,n,i){return n&&He(r.prototype,n),i&&He(r,i),Object.defineProperty(r,"prototype",{writable:!1}),r}function Q(r){return Q=Object.setPrototypeOf?Object.getPrototypeOf.bind():function(n){return n.__proto__||Object.getPrototypeOf(n)},Q(r)}function yt(){try{var r=!Boolean.prototype.valueOf.call(Reflect.construct(Boolean,[],function(){}))}catch{}return(yt=function(){return!!r})()}function jt(r){if(r===void 0)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return r}function Zt(r,n){if(n&&(typeof n=="object"||typeof n=="function"))return n;if(n!==void 0)throw new TypeError("Derived constructors may only return object or undefined");return jt(r)}function I(r,n,i){return n=Q(n),Zt(r,yt()?Reflect.construct(n,i||[],Q(r).constructor):n.apply(r,i))}function xe(r,n){return xe=Object.setPrototypeOf?Object.setPrototypeOf.bind():function(i,e){return i.__proto__=e,i},xe(r,n)}function G(r,n){if(typeof n!="function"&&n!==null)throw new TypeError("Super expression must either be null or a function");r.prototype=Object.create(n&&n.prototype,{constructor:{value:r,writable:!0,configurable:!0}}),Object.defineProperty(r,"prototype",{writable:!1}),n&&xe(r,n)}function qt(r){if(Array.isArray(r))return r}function Yt(r,n){var i=r==null?null:typeof Symbol<"u"&&r[Symbol.iterator]||r["@@iterator"];if(i!=null){var e,t,a,o,s=[],l=!0,h=!1;try{if(a=(i=i.call(r)).next,n===0){if(Object(i)!==i)return;l=!1}else for(;!(l=(e=a.call(i)).done)&&(s.push(e.value),s.length!==n);l=!0);}catch(u){h=!0,t=u}finally{try{if(!l&&i.return!=null&&(o=i.return(),Object(o)!==o))return}finally{if(h)throw t}}return s}}function Se(r,n){(n==null||n>r.length)&&(n=r.length);for(var i=0,e=Array(n);i<n;i++)e[i]=r[i];return e}function Tt(r,n){if(r){if(typeof r=="string")return Se(r,n);var i={}.toString.call(r).slice(8,-1);return i==="Object"&&r.constructor&&(i=r.constructor.name),i==="Map"||i==="Set"?Array.from(r):i==="Arguments"||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(i)?Se(r,n):void 0}}function Xt(){throw new TypeError(`Invalid attempt to destructure non-iterable instance.
1
+ import{g as Bt,t as S,r as C}from"./vendor-tanstack-Dock0eH1.js";import{e as Ht,G as Wt}from"./SiteHealthSection-DhpNThBa.js";import"./index-ClNW_gZV.js";import"./vendor-radix-4UOaVWza.js";import"./vendor-recharts-D8rt5lKn.js";import"./vendor-lucide-nYKv-BB7.js";import"./vendor-markdown-Bn7fRwrx.js";import"./vendor-yaml-GWJz5H2G.js";import"./ChartPrimitives-BoYe2M-i.js";function Vt(r,n){if(typeof r!="object"||!r)return r;var i=r[Symbol.toPrimitive];if(i!==void 0){var e=i.call(r,n);if(typeof e!="object")return e;throw new TypeError("@@toPrimitive must return a primitive value.")}return String(r)}function ae(r){var n=Vt(r,"string");return typeof n=="symbol"?n:n+""}function A(r,n){if(!(r instanceof n))throw new TypeError("Cannot call a class as a function")}function He(r,n){for(var i=0;i<n.length;i++){var e=n[i];e.enumerable=e.enumerable||!1,e.configurable=!0,"value"in e&&(e.writable=!0),Object.defineProperty(r,ae(e.key),e)}}function L(r,n,i){return n&&He(r.prototype,n),i&&He(r,i),Object.defineProperty(r,"prototype",{writable:!1}),r}function Q(r){return Q=Object.setPrototypeOf?Object.getPrototypeOf.bind():function(n){return n.__proto__||Object.getPrototypeOf(n)},Q(r)}function yt(){try{var r=!Boolean.prototype.valueOf.call(Reflect.construct(Boolean,[],function(){}))}catch{}return(yt=function(){return!!r})()}function jt(r){if(r===void 0)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return r}function Zt(r,n){if(n&&(typeof n=="object"||typeof n=="function"))return n;if(n!==void 0)throw new TypeError("Derived constructors may only return object or undefined");return jt(r)}function I(r,n,i){return n=Q(n),Zt(r,yt()?Reflect.construct(n,i||[],Q(r).constructor):n.apply(r,i))}function xe(r,n){return xe=Object.setPrototypeOf?Object.setPrototypeOf.bind():function(i,e){return i.__proto__=e,i},xe(r,n)}function G(r,n){if(typeof n!="function"&&n!==null)throw new TypeError("Super expression must either be null or a function");r.prototype=Object.create(n&&n.prototype,{constructor:{value:r,writable:!0,configurable:!0}}),Object.defineProperty(r,"prototype",{writable:!1}),n&&xe(r,n)}function qt(r){if(Array.isArray(r))return r}function Yt(r,n){var i=r==null?null:typeof Symbol<"u"&&r[Symbol.iterator]||r["@@iterator"];if(i!=null){var e,t,a,o,s=[],l=!0,h=!1;try{if(a=(i=i.call(r)).next,n===0){if(Object(i)!==i)return;l=!1}else for(;!(l=(e=a.call(i)).done)&&(s.push(e.value),s.length!==n);l=!0);}catch(u){h=!0,t=u}finally{try{if(!l&&i.return!=null&&(o=i.return(),Object(o)!==o))return}finally{if(h)throw t}}return s}}function Se(r,n){(n==null||n>r.length)&&(n=r.length);for(var i=0,e=Array(n);i<n;i++)e[i]=r[i];return e}function Tt(r,n){if(r){if(typeof r=="string")return Se(r,n);var i={}.toString.call(r).slice(8,-1);return i==="Object"&&r.constructor&&(i=r.constructor.name),i==="Map"||i==="Set"?Array.from(r):i==="Arguments"||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(i)?Se(r,n):void 0}}function Xt(){throw new TypeError(`Invalid attempt to destructure non-iterable instance.
2
2
  In order to be iterable, non-array objects must have a [Symbol.iterator]() method.`)}function ee(r,n){return qt(r)||Yt(r,n)||Tt(r,n)||Xt()}var pe={black:"#000000",silver:"#C0C0C0",gray:"#808080",grey:"#808080",white:"#FFFFFF",maroon:"#800000",red:"#FF0000",purple:"#800080",fuchsia:"#FF00FF",green:"#008000",lime:"#00FF00",olive:"#808000",yellow:"#FFFF00",navy:"#000080",blue:"#0000FF",teal:"#008080",aqua:"#00FFFF",darkblue:"#00008B",mediumblue:"#0000CD",darkgreen:"#006400",darkcyan:"#008B8B",deepskyblue:"#00BFFF",darkturquoise:"#00CED1",mediumspringgreen:"#00FA9A",springgreen:"#00FF7F",cyan:"#00FFFF",midnightblue:"#191970",dodgerblue:"#1E90FF",lightseagreen:"#20B2AA",forestgreen:"#228B22",seagreen:"#2E8B57",darkslategray:"#2F4F4F",darkslategrey:"#2F4F4F",limegreen:"#32CD32",mediumseagreen:"#3CB371",turquoise:"#40E0D0",royalblue:"#4169E1",steelblue:"#4682B4",darkslateblue:"#483D8B",mediumturquoise:"#48D1CC",indigo:"#4B0082",darkolivegreen:"#556B2F",cadetblue:"#5F9EA0",cornflowerblue:"#6495ED",rebeccapurple:"#663399",mediumaquamarine:"#66CDAA",dimgray:"#696969",dimgrey:"#696969",slateblue:"#6A5ACD",olivedrab:"#6B8E23",slategray:"#708090",slategrey:"#708090",lightslategray:"#778899",lightslategrey:"#778899",mediumslateblue:"#7B68EE",lawngreen:"#7CFC00",chartreuse:"#7FFF00",aquamarine:"#7FFFD4",skyblue:"#87CEEB",lightskyblue:"#87CEFA",blueviolet:"#8A2BE2",darkred:"#8B0000",darkmagenta:"#8B008B",saddlebrown:"#8B4513",darkseagreen:"#8FBC8F",lightgreen:"#90EE90",mediumpurple:"#9370DB",darkviolet:"#9400D3",palegreen:"#98FB98",darkorchid:"#9932CC",yellowgreen:"#9ACD32",sienna:"#A0522D",brown:"#A52A2A",darkgray:"#A9A9A9",darkgrey:"#A9A9A9",lightblue:"#ADD8E6",greenyellow:"#ADFF2F",paleturquoise:"#AFEEEE",lightsteelblue:"#B0C4DE",powderblue:"#B0E0E6",firebrick:"#B22222",darkgoldenrod:"#B8860B",mediumorchid:"#BA55D3",rosybrown:"#BC8F8F",darkkhaki:"#BDB76B",mediumvioletred:"#C71585",indianred:"#CD5C5C",peru:"#CD853F",chocolate:"#D2691E",tan:"#D2B48C",lightgray:"#D3D3D3",lightgrey:"#D3D3D3",thistle:"#D8BFD8",orchid:"#DA70D6",goldenrod:"#DAA520",palevioletred:"#DB7093",crimson:"#DC143C",gainsboro:"#DCDCDC",plum:"#DDA0DD",burlywood:"#DEB887",lightcyan:"#E0FFFF",lavender:"#E6E6FA",darksalmon:"#E9967A",violet:"#EE82EE",palegoldenrod:"#EEE8AA",lightcoral:"#F08080",khaki:"#F0E68C",aliceblue:"#F0F8FF",honeydew:"#F0FFF0",azure:"#F0FFFF",sandybrown:"#F4A460",wheat:"#F5DEB3",beige:"#F5F5DC",whitesmoke:"#F5F5F5",mintcream:"#F5FFFA",ghostwhite:"#F8F8FF",salmon:"#FA8072",antiquewhite:"#FAEBD7",linen:"#FAF0E6",lightgoldenrodyellow:"#FAFAD2",oldlace:"#FDF5E6",magenta:"#FF00FF",deeppink:"#FF1493",orangered:"#FF4500",tomato:"#FF6347",hotpink:"#FF69B4",coral:"#FF7F50",darkorange:"#FF8C00",lightsalmon:"#FFA07A",orange:"#FFA500",lightpink:"#FFB6C1",pink:"#FFC0CB",gold:"#FFD700",peachpuff:"#FFDAB9",navajowhite:"#FFDEAD",moccasin:"#FFE4B5",bisque:"#FFE4C4",mistyrose:"#FFE4E1",blanchedalmond:"#FFEBCD",papayawhip:"#FFEFD5",lavenderblush:"#FFF0F5",seashell:"#FFF5EE",cornsilk:"#FFF8DC",lemonchiffon:"#FFFACD",floralwhite:"#FFFAF0",snow:"#FFFAFA",lightyellow:"#FFFFE0",ivory:"#FFFFF0"},Ct=new Int8Array(4),be=new Int32Array(Ct.buffer,0,1),$t=new Float32Array(Ct.buffer,0,1),Kt=/^\s*rgba?\s*\(/,Jt=/^\s*rgba?\s*\(\s*([0-9]*)\s*,\s*([0-9]*)\s*,\s*([0-9]*)(?:\s*,\s*(.*)?)?\)\s*$/;function Qt(r){var n=0,i=0,e=0,t=1;if(r[0]==="#")r.length===4?(n=parseInt(r.charAt(1)+r.charAt(1),16),i=parseInt(r.charAt(2)+r.charAt(2),16),e=parseInt(r.charAt(3)+r.charAt(3),16)):(n=parseInt(r.charAt(1)+r.charAt(2),16),i=parseInt(r.charAt(3)+r.charAt(4),16),e=parseInt(r.charAt(5)+r.charAt(6),16)),r.length===9&&(t=parseInt(r.charAt(7)+r.charAt(8),16)/255);else if(Kt.test(r)){var a=r.match(Jt);a&&(n=+a[1],i=+a[2],e=+a[3],a[4]&&(t=+a[4]))}return{r:n,g:i,b:e,a:t}}var J={};for(var le in pe)J[le]=oe(pe[le]),J[pe[le]]=J[le];function Rt(r,n,i,e,t){return be[0]=e<<24|i<<16|n<<8|r,be[0]=be[0]&4278190079,$t[0]}function oe(r){if(r=r.toLowerCase(),typeof J[r]<"u")return J[r];var n=Qt(r),i=n.r,e=n.g,t=n.b,a=n.a;a=a*255|0;var o=Rt(i,e,t,a);return J[r]=o,o}var Ee={};function _t(r){if(typeof Ee[r]<"u")return Ee[r];var n=(r&16711680)>>>16,i=(r&65280)>>>8,e=r&255,t=255,a=Rt(n,i,e,t);return Ee[r]=a,a}function We(r,n,i,e){return i+(n<<8)+(r<<16)}function Ve(r,n,i,e,t,a){var o=Math.floor(i/a*t),s=Math.floor(r.drawingBufferHeight/a-e/a*t),l=new Uint8Array(4);r.bindFramebuffer(r.FRAMEBUFFER,n),r.readPixels(o,s,1,1,r.RGBA,r.UNSIGNED_BYTE,l);var h=ee(l,4),u=h[0],d=h[1],f=h[2],g=h[3];return[u,d,f,g]}function c(r,n,i){return(n=ae(n))in r?Object.defineProperty(r,n,{value:i,enumerable:!0,configurable:!0,writable:!0}):r[n]=i,r}function je(r,n){var i=Object.keys(r);if(Object.getOwnPropertySymbols){var e=Object.getOwnPropertySymbols(r);n&&(e=e.filter(function(t){return Object.getOwnPropertyDescriptor(r,t).enumerable})),i.push.apply(i,e)}return i}function b(r){for(var n=1;n<arguments.length;n++){var i=arguments[n]!=null?arguments[n]:{};n%2?je(Object(i),!0).forEach(function(e){c(r,e,i[e])}):Object.getOwnPropertyDescriptors?Object.defineProperties(r,Object.getOwnPropertyDescriptors(i)):je(Object(i)).forEach(function(e){Object.defineProperty(r,e,Object.getOwnPropertyDescriptor(i,e))})}return r}function ei(r,n){for(;!{}.hasOwnProperty.call(r,n)&&(r=Q(r))!==null;);return r}function Ae(){return Ae=typeof Reflect<"u"&&Reflect.get?Reflect.get.bind():function(r,n,i){var e=ei(r,n);if(e){var t=Object.getOwnPropertyDescriptor(e,n);return t.get?t.get.call(arguments.length<3?r:i):t.value}},Ae.apply(null,arguments)}function wt(r,n,i,e){var t=Ae(Q(r.prototype),n,i);return typeof t=="function"?function(a){return t.apply(i,a)}:t}function ti(r){return r.normalized?1:r.size}function ye(r){var n=0;return r.forEach(function(i){return n+=ti(i)}),n}function xt(r,n,i){var e=r==="VERTEX"?n.VERTEX_SHADER:n.FRAGMENT_SHADER,t=n.createShader(e);if(t===null)throw new Error("loadShader: error while creating the shader");n.shaderSource(t,i),n.compileShader(t);var a=n.getShaderParameter(t,n.COMPILE_STATUS);if(!a){var o=n.getShaderInfoLog(t);throw n.deleteShader(t),new Error(`loadShader: error while compiling the shader:
3
3
  `.concat(o,`
4
4
  `).concat(i))}return t}function ii(r,n){return xt("VERTEX",r,n)}function ri(r,n){return xt("FRAGMENT",r,n)}function ni(r,n){var i=r.createProgram();if(i===null)throw new Error("loadProgram: error while creating the program.");var e,t;for(e=0,t=n.length;e<t;e++)r.attachShader(i,n[e]);r.linkProgram(i);var a=r.getProgramParameter(i,r.LINK_STATUS);if(!a){var o=r.getProgramInfoLog(i);throw r.deleteProgram(i),new Error("loadProgram: error while linking the program: ".concat(o))}return i}function Ze(r){var n=r.gl,i=r.buffer,e=r.program,t=r.vertexShader,a=r.fragmentShader;n.deleteShader(t),n.deleteShader(a),n.deleteProgram(e),n.deleteBuffer(i)}var qe=`#define PICKING_MODE
package/assets/index.html CHANGED
@@ -12,7 +12,7 @@
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-DpQ_-QC_.js"></script>
15
+ <script type="module" crossorigin src="./assets/index-ClNW_gZV.js"></script>
16
16
  <link rel="modulepreload" crossorigin href="./assets/vendor-tanstack-Dock0eH1.js">
17
17
  <link rel="modulepreload" crossorigin href="./assets/vendor-radix-4UOaVWza.js">
18
18
  <link rel="modulepreload" crossorigin href="./assets/vendor-recharts-D8rt5lKn.js">
@@ -91,7 +91,7 @@ import {
91
91
  trafficConnectWordpressRequestSchema,
92
92
  trafficEventKindSchema,
93
93
  trafficSeriesGranularitySchema
94
- } from "./chunk-EGGQSFQL.js";
94
+ } from "./chunk-WGN2VT7L.js";
95
95
 
96
96
  // src/config.ts
97
97
  import fs from "fs";
@@ -9,7 +9,7 @@ import {
9
9
  loadConfig,
10
10
  loadConfigRaw,
11
11
  saveConfigPatch
12
- } from "./chunk-YXDCVM5U.js";
12
+ } from "./chunk-BZDNTUCZ.js";
13
13
  import {
14
14
  CC_CACHE_DIR,
15
15
  DUCKDB_SPEC,
@@ -145,7 +145,7 @@ import {
145
145
  siteCrawlSnapshots,
146
146
  toAlertView,
147
147
  usageCounters
148
- } from "./chunk-PXTSQ67Z.js";
148
+ } from "./chunk-XEWBDO5L.js";
149
149
  import {
150
150
  AGENT_MEMORY_VALUE_MAX_BYTES,
151
151
  AGENT_PROVIDER_IDS,
@@ -282,7 +282,7 @@ import {
282
282
  validationError,
283
283
  winnabilityClassLabel,
284
284
  withRetry
285
- } from "./chunk-EGGQSFQL.js";
285
+ } from "./chunk-WGN2VT7L.js";
286
286
 
287
287
  // src/telemetry.ts
288
288
  import crypto from "crypto";
@@ -11829,7 +11829,7 @@ function readStoredGroundingSources(rawResponse) {
11829
11829
  return result;
11830
11830
  }
11831
11831
  async function backfillInsightsCommand(project, opts) {
11832
- const { IntelligenceService: IntelligenceService2 } = await import("./intelligence-service-H7756PBD.js");
11832
+ const { IntelligenceService: IntelligenceService2 } = await import("./intelligence-service-PPYG6NJP.js");
11833
11833
  const config = loadConfig();
11834
11834
  const db = createClient(config.database);
11835
11835
  migrate(db);
@@ -5,11 +5,11 @@ import {
5
5
  installSkills,
6
6
  loadConfigRaw,
7
7
  saveConfigPatch
8
- } from "./chunk-YXDCVM5U.js";
8
+ } from "./chunk-BZDNTUCZ.js";
9
9
  import {
10
10
  SKILL_MANIFEST_FILENAME,
11
11
  SkillsClients
12
- } from "./chunk-EGGQSFQL.js";
12
+ } from "./chunk-WGN2VT7L.js";
13
13
 
14
14
  // src/skills-autosync.ts
15
15
  import fs from "fs";
@@ -7650,6 +7650,47 @@ var gscPerformanceTrendsSchema = z19.object({
7650
7650
  ctr: linearTrendSchema.nullable(),
7651
7651
  position: linearTrendSchema.nullable()
7652
7652
  });
7653
+ var gscPeriodTotalsSchema = z19.object({
7654
+ startDate: z19.string(),
7655
+ endDate: z19.string(),
7656
+ clicks: z19.number(),
7657
+ impressions: z19.number(),
7658
+ /** The period's own `clicks / impressions`, never a mean of daily ratios. */
7659
+ ctr: z19.number().nullable(),
7660
+ /** Impression-weighted mean position, or null when no day carried one. */
7661
+ position: z19.number().nullable(),
7662
+ /**
7663
+ * Which table the figures came from. `gsc_daily_totals` (property-daily) and
7664
+ * `SUM(gsc_search_data)` (dimensioned) are not interchangeable: on one real
7665
+ * property-month the same period reads 1,142 clicks / 34,916 impressions from
7666
+ * the first and 792 / 45,266 from the second.
7667
+ */
7668
+ source: z19.enum(["property-daily", "dimensioned", "mixed", "empty"])
7669
+ });
7670
+ var gscPeriodComparisonSchema = z19.object({
7671
+ /** Length of EACH period in calendar days. */
7672
+ days: z19.number(),
7673
+ prior: gscPeriodTotalsSchema,
7674
+ trailing: gscPeriodTotalsSchema,
7675
+ /**
7676
+ * False when either period contains dimensioned fallback totals, in which
7677
+ * case every `change` is null. Empty/property-daily halves are comparable;
7678
+ * `SUM(gsc_search_data)` is never valid for property totals.
7679
+ */
7680
+ comparable: z19.boolean(),
7681
+ /**
7682
+ * Relative change as a ratio (0.5 = +50%), null where the prior period gives
7683
+ * nothing to divide by or the trailing metric is unavailable. The sign is
7684
+ * mathematical: a POSITIVE `position` means the rank number rose, which is
7685
+ * worse. Desirability is the renderer's call.
7686
+ */
7687
+ change: z19.object({
7688
+ clicks: z19.number().nullable(),
7689
+ impressions: z19.number().nullable(),
7690
+ ctr: z19.number().nullable(),
7691
+ position: z19.number().nullable()
7692
+ })
7693
+ });
7653
7694
  var gscPerformanceDailyDtoSchema = z19.object({
7654
7695
  totals: z19.object({
7655
7696
  clicks: z19.number(),
@@ -7681,7 +7722,14 @@ var gscPerformanceDailyDtoSchema = z19.object({
7681
7722
  * Optional for the same reason as `window`: a server older than this field
7682
7723
  * omits it, and the chart guards for that skew.
7683
7724
  */
7684
- trends: gscPerformanceTrendsSchema.optional()
7725
+ trends: gscPerformanceTrendsSchema.optional(),
7726
+ /**
7727
+ * Optional for the same reason as `window` and `trends`, and additionally
7728
+ * null when the window is too short to split into two periods, has no
7729
+ * evidence, or extends beyond the project's known GSC data frontier. A
7730
+ * consumer must render the absence rather than substitute a percentage.
7731
+ */
7732
+ periodComparison: gscPeriodComparisonSchema.nullable().optional()
7685
7733
  });
7686
7734
  var gscTopPageRowSchema = z19.object({
7687
7735
  page: z19.string(),
@@ -628,7 +628,7 @@ import {
628
628
  wordpressSchemaDeployResultDtoSchema,
629
629
  wordpressSchemaStatusResultDtoSchema,
630
630
  wordpressStatusDtoSchema
631
- } from "./chunk-EGGQSFQL.js";
631
+ } from "./chunk-WGN2VT7L.js";
632
632
 
633
633
  // src/intelligence-service.ts
634
634
  import { eq as eq60, desc as desc27, asc as asc11, and as and48, ne as ne8, or as or14, inArray as inArray21, gte as gte14, lte as lte12 } from "drizzle-orm";
@@ -37150,6 +37150,88 @@ function formatNotification(row) {
37150
37150
  import crypto30 from "crypto";
37151
37151
  import { eq as eq39, and as and30, desc as desc17, sql as sql13, inArray as inArray16 } from "drizzle-orm";
37152
37152
 
37153
+ // ../api-routes/src/gsc-period-comparison.ts
37154
+ var DAY_MS = 864e5;
37155
+ function calendarDateMs(value) {
37156
+ if (!/^\d{4}-\d{2}-\d{2}$/.test(value)) return null;
37157
+ const parsed = /* @__PURE__ */ new Date(`${value}T00:00:00Z`);
37158
+ if (Number.isNaN(parsed.getTime()) || parsed.toISOString().slice(0, 10) !== value) return null;
37159
+ return parsed.getTime();
37160
+ }
37161
+ function calendarDateAt(ms) {
37162
+ return new Date(ms).toISOString().slice(0, 10);
37163
+ }
37164
+ function relativeChange(trailing, prior) {
37165
+ if (trailing === null || prior === null) return null;
37166
+ if (!Number.isFinite(trailing) || !Number.isFinite(prior)) return null;
37167
+ if (prior <= 0) return null;
37168
+ return (trailing - prior) / prior;
37169
+ }
37170
+ function aggregate(startDate, endDate, byDate) {
37171
+ let clicks = 0;
37172
+ let impressions = 0;
37173
+ let positionWeight = 0;
37174
+ let positionWeighted = 0;
37175
+ let propertyDays = 0;
37176
+ let dimensionedDays = 0;
37177
+ for (const row of byDate.values()) {
37178
+ if (row.date < startDate || row.date > endDate) continue;
37179
+ if (row.fromPropertyTotals) propertyDays += 1;
37180
+ else dimensionedDays += 1;
37181
+ clicks += row.clicks;
37182
+ impressions += row.impressions;
37183
+ if (row.position !== null && row.impressions > 0) {
37184
+ positionWeight += row.impressions;
37185
+ positionWeighted += row.position * row.impressions;
37186
+ }
37187
+ }
37188
+ return {
37189
+ startDate,
37190
+ endDate,
37191
+ clicks,
37192
+ impressions,
37193
+ // CTR is a ratio of the period's own totals. Averaging the daily ratios
37194
+ // instead would weight a 1-impression day equally with a 1000-impression
37195
+ // one and would not reconcile with the clicks and impressions beside it.
37196
+ ctr: impressions > 0 ? clicks / impressions : null,
37197
+ position: positionWeight > 0 ? positionWeighted / positionWeight : null,
37198
+ // Empty is its own provenance. It is a real zero-count period, not evidence
37199
+ // from the invalid-for-totals dimensioned table.
37200
+ source: propertyDays > 0 && dimensionedDays > 0 ? "mixed" : propertyDays > 0 ? "property-daily" : dimensionedDays > 0 ? "dimensioned" : "empty"
37201
+ };
37202
+ }
37203
+ function computeGscPeriodComparison(daily, bounds) {
37204
+ const first = bounds?.startDate ?? daily[0]?.date;
37205
+ const last = bounds?.endDate ?? daily[daily.length - 1]?.date;
37206
+ if (!first || !last) return null;
37207
+ const firstMs = calendarDateMs(first);
37208
+ const lastMs = calendarDateMs(last);
37209
+ if (firstMs === null || lastMs === null || firstMs > lastMs) return null;
37210
+ const spanDays = Math.floor((lastMs - firstMs) / DAY_MS) + 1;
37211
+ const periodDays = Math.floor(spanDays / 2);
37212
+ if (periodDays < 1) return null;
37213
+ const byDate = new Map(daily.map((row) => [row.date, row]));
37214
+ const trailingStart = calendarDateAt(lastMs - (periodDays - 1) * DAY_MS);
37215
+ const priorEnd = calendarDateAt(lastMs - periodDays * DAY_MS);
37216
+ const priorStart = calendarDateAt(lastMs - (periodDays * 2 - 1) * DAY_MS);
37217
+ const prior = aggregate(priorStart, priorEnd, byDate);
37218
+ const trailing = aggregate(trailingStart, last, byDate);
37219
+ if (prior.source === "empty" && trailing.source === "empty") return null;
37220
+ const comparable = prior.source !== "dimensioned" && prior.source !== "mixed" && trailing.source !== "dimensioned" && trailing.source !== "mixed";
37221
+ return {
37222
+ days: periodDays,
37223
+ prior,
37224
+ trailing,
37225
+ comparable,
37226
+ change: {
37227
+ clicks: comparable ? relativeChange(trailing.clicks, prior.clicks) : null,
37228
+ impressions: comparable ? relativeChange(trailing.impressions, prior.impressions) : null,
37229
+ ctr: comparable ? relativeChange(trailing.ctr, prior.ctr) : null,
37230
+ position: comparable ? relativeChange(trailing.position, prior.position) : null
37231
+ }
37232
+ };
37233
+ }
37234
+
37153
37235
  // ../api-routes/src/gbp-summary.ts
37154
37236
  function computeMetricTotals(rows) {
37155
37237
  const totals = {};
@@ -39061,6 +39143,13 @@ function resolveReportedWindow(resolved, startDate, endDate) {
39061
39143
  };
39062
39144
  }
39063
39145
  function assertForwardRange(startDate, endDate) {
39146
+ for (const [field, value] of [["startDate", startDate], ["endDate", endDate]]) {
39147
+ if (value === void 0) continue;
39148
+ const parsed = /^\d{4}-\d{2}-\d{2}$/.test(value) ? /* @__PURE__ */ new Date(`${value}T00:00:00Z`) : null;
39149
+ if (parsed === null || Number.isNaN(parsed.getTime()) || parsed.toISOString().slice(0, 10) !== value) {
39150
+ throw validationError(`Invalid ${field} "${value}". Expected a calendar date as YYYY-MM-DD.`);
39151
+ }
39152
+ }
39064
39153
  if (startDate && endDate && startDate > endDate) {
39065
39154
  throw validationError(`startDate "${startDate}" is after endDate "${endDate}".`);
39066
39155
  }
@@ -39576,6 +39665,10 @@ async function googleRoutes(app, opts) {
39576
39665
  const row = byDate.get(date);
39577
39666
  return row ? pick(row) : null;
39578
39667
  });
39668
+ const reportedWindow = resolveReportedWindow(resolvedWindow, startDate, endDate);
39669
+ const comparisonStart = reportedWindow.startDate ?? daily[0]?.date;
39670
+ const comparisonEnd = reportedWindow.endDate ?? daily[daily.length - 1]?.date;
39671
+ const comparisonEndsWithinKnownData = reportedWindow.latestDataDate !== null && comparisonEnd <= reportedWindow.latestDataDate;
39579
39672
  return {
39580
39673
  totals: {
39581
39674
  clicks: totalClicks,
@@ -39601,7 +39694,7 @@ async function googleRoutes(app, opts) {
39601
39694
  // contain the rows beside it. When only one side is given, the other is
39602
39695
  // dropped rather than reported reversed: an absent bound is honest about
39603
39696
  // being unspecified, a reversed pair is not.
39604
- window: resolveReportedWindow(resolvedWindow, startDate, endDate),
39697
+ window: reportedWindow,
39605
39698
  // Fitted server-side so the dashboard, the CLI, and the report all draw
39606
39699
  // the SAME line (UI/CLI parity — a chart-only regression is invisible to
39607
39700
  // an agent), and fitted over the CALENDAR, not over the rows.
@@ -39610,7 +39703,19 @@ async function googleRoutes(app, opts) {
39610
39703
  impressions: linearTrend(densify((d) => d.impressions)),
39611
39704
  ctr: linearTrend(densify((d) => d.ctr)),
39612
39705
  position: linearTrend(densify((d) => d.position))
39613
- }
39706
+ },
39707
+ // The headline percentages come from HERE, not from `trends`. The fitted
39708
+ // line answers "which way is it going"; it cannot answer "by how much"
39709
+ // without a baseline, and its own start value is not one — unconstrained,
39710
+ // it goes negative for a metric that cannot be. Computed server-side for
39711
+ // the same UI/CLI parity reason as the fit: a percentage derived in a
39712
+ // chart component is invisible to an agent.
39713
+ periodComparison: comparisonStart && comparisonEnd && comparisonEndsWithinKnownData ? computeGscPeriodComparison(
39714
+ // The source tag is the comparison module's input, NOT part of the
39715
+ // response: `daily` on the wire stays exactly what the DTO declares.
39716
+ daily.map((d) => ({ ...d, fromPropertyTotals: propertyDates.has(d.date) })),
39717
+ { startDate: comparisonStart, endDate: comparisonEnd }
39718
+ ) : null
39614
39719
  };
39615
39720
  });
39616
39721
  app.get("/projects/:name/google/gsc/top-pages", async (request) => {
@@ -41120,6 +41225,13 @@ function oauthConfirmationHtml(input) {
41120
41225
  return `<html><body style="font-family:system-ui;text-align:center;padding:60px"><h2>Confirm connection</h2><p>Connect ${escapeHtml2(label)} to ${escapeHtml2(input.projectName)}?</p><form method="post" action="${escapeHtml2(action)}"><button type="submit">Confirm connection</button></form><p style="color:#888">This must be confirmed in the same signed-in browser that started the connection.</p></body></html>`;
41121
41226
  }
41122
41227
  async function googleMarketingRoutes(app, opts) {
41228
+ app.addContentTypeParser(
41229
+ "application/x-www-form-urlencoded",
41230
+ { parseAs: "string" },
41231
+ (_request, _body, done) => {
41232
+ done(null, {});
41233
+ }
41234
+ );
41123
41235
  const pendingOAuthFlows = new PendingGoogleMarketingOAuthFlows();
41124
41236
  let stateSecret = null;
41125
41237
  if (opts.googleStateSecret !== void 0) {
@@ -62039,7 +62151,7 @@ var GTM_REQUIRED_OAUTH_SCOPES = [
62039
62151
  ];
62040
62152
  var FRESH_SNAPSHOT_WARN_DAYS = 7;
62041
62153
  var FRESH_SNAPSHOT_FAIL_DAYS = 30;
62042
- var DAY_MS = 24 * 60 * 60 * 1e3;
62154
+ var DAY_MS2 = 24 * 60 * 60 * 1e3;
62043
62155
  function unavailableStatus() {
62044
62156
  return {
62045
62157
  status: CheckStatuses.skipped,
@@ -62126,7 +62238,7 @@ function snapshotOutput(provider, latestSnapshotAt, now) {
62126
62238
  details: { latestSnapshotAt }
62127
62239
  };
62128
62240
  }
62129
- const ageDays = (now.getTime() - snapshotMs) / DAY_MS;
62241
+ const ageDays = (now.getTime() - snapshotMs) / DAY_MS2;
62130
62242
  const details = { latestSnapshotAt, ageDays: Math.max(0, Math.round(ageDays)) };
62131
62243
  if (ageDays < 0) {
62132
62244
  return {
package/dist/cli.js CHANGED
@@ -26,11 +26,11 @@ import {
26
26
  showFirstRunNotice,
27
27
  trackCliCommandFinished,
28
28
  trackEvent
29
- } from "./chunk-TI3SZAVI.js";
29
+ } from "./chunk-OHSUOEVB.js";
30
30
  import {
31
31
  autoSyncSkills,
32
32
  formatAutoSyncNotice
33
- } from "./chunk-U5JTZM66.js";
33
+ } from "./chunk-WFVK3XC7.js";
34
34
  import {
35
35
  CliError,
36
36
  EXIT_SYSTEM_ERROR,
@@ -55,7 +55,7 @@ import {
55
55
  saveConfigPatch,
56
56
  systemError,
57
57
  usageError
58
- } from "./chunk-YXDCVM5U.js";
58
+ } from "./chunk-BZDNTUCZ.js";
59
59
  import {
60
60
  CLOUDFLARE_WORKER_BINDINGS,
61
61
  CLOUDFLARE_WORKER_GENERATED_MARKER,
@@ -69,7 +69,7 @@ import {
69
69
  projects,
70
70
  queries,
71
71
  renderReportHtml
72
- } from "./chunk-PXTSQ67Z.js";
72
+ } from "./chunk-XEWBDO5L.js";
73
73
  import {
74
74
  AdsDeliverySnapshotStatuses,
75
75
  AdsHistoricalCampaignRollupStatuses,
@@ -137,7 +137,7 @@ import {
137
137
  providerQuotaPolicySchema,
138
138
  resolveProviderInput,
139
139
  winnabilityClassSchema
140
- } from "./chunk-EGGQSFQL.js";
140
+ } from "./chunk-WGN2VT7L.js";
141
141
 
142
142
  // src/cli.ts
143
143
  import { pathToFileURL } from "url";
@@ -7792,6 +7792,41 @@ async function googlePerformanceDaily(project, opts) {
7792
7792
  Trend (least-squares fit over ${days} day${days === 1 ? "" : "s"}):`);
7793
7793
  for (const line of trendLines) console.log(line);
7794
7794
  }
7795
+ const cmp = data.periodComparison;
7796
+ if (cmp && !cmp.comparable) {
7797
+ console.log(
7798
+ `
7799
+ No period comparison: period comparison needs property-level daily data. Sync again, or pick a range covered by property totals.`
7800
+ );
7801
+ } else if (cmp) {
7802
+ const pct4 = (ratio, prior, trailing, inverted) => {
7803
+ if (ratio === null) {
7804
+ if (prior !== null && trailing !== null && prior <= 0 && trailing > 0) {
7805
+ return `new in last ${cmp.days} day${cmp.days === 1 ? "" : "s"}`;
7806
+ }
7807
+ if (prior === null || prior <= 0) return "no prior period to compare";
7808
+ if (trailing === null) return `no value in last ${cmp.days} day${cmp.days === 1 ? "" : "s"}`;
7809
+ return "comparison unavailable";
7810
+ }
7811
+ if (ratio === 0) return "no change";
7812
+ const better = inverted ? ratio < 0 : ratio > 0;
7813
+ const magnitude = Math.abs(ratio * 100);
7814
+ const shown = magnitude < 0.1 ? "<0.1" : magnitude.toFixed(1);
7815
+ return `${ratio > 0 ? "+" : "-"}${shown}% ${better ? "better" : "worse"}`;
7816
+ };
7817
+ console.log(
7818
+ `
7819
+ Last ${cmp.days} day${cmp.days === 1 ? "" : "s"} (${cmp.trailing.startDate} to ${cmp.trailing.endDate}) vs prior ${cmp.days} (${cmp.prior.startDate} to ${cmp.prior.endDate}):`
7820
+ );
7821
+ for (const [label, ratio, prior, trailing, inverted] of [
7822
+ ["Clicks", cmp.change.clicks, cmp.prior.clicks, cmp.trailing.clicks, false],
7823
+ ["Impressions", cmp.change.impressions, cmp.prior.impressions, cmp.trailing.impressions, false],
7824
+ ["CTR", cmp.change.ctr, cmp.prior.ctr, cmp.trailing.ctr, false],
7825
+ ["Position", cmp.change.position, cmp.prior.position, cmp.trailing.position, true]
7826
+ ]) {
7827
+ console.log(` ${`${label}:`.padEnd(13)}${pct4(ratio, prior, trailing, inverted)}`);
7828
+ }
7829
+ }
7795
7830
  console.log();
7796
7831
  console.log(` ${"DATE".padEnd(12)}${"CLICKS".padStart(10)}${"IMPR".padStart(12)}${"CTR".padStart(10)}${"POS".padStart(9)}`);
7797
7832
  console.log(` ${"\u2500".repeat(12)}${"\u2500".repeat(10)}${"\u2500".repeat(12)}${"\u2500".repeat(10)}${"\u2500".repeat(9)}`);
package/dist/index.js CHANGED
@@ -3,12 +3,12 @@ import {
3
3
  createGoogleMarketingCredentialStore,
4
4
  createGoogleMarketingRuntime,
5
5
  createServer
6
- } from "./chunk-TI3SZAVI.js";
6
+ } from "./chunk-OHSUOEVB.js";
7
7
  import {
8
8
  loadConfig
9
- } from "./chunk-YXDCVM5U.js";
10
- import "./chunk-PXTSQ67Z.js";
11
- import "./chunk-EGGQSFQL.js";
9
+ } from "./chunk-BZDNTUCZ.js";
10
+ import "./chunk-XEWBDO5L.js";
11
+ import "./chunk-WGN2VT7L.js";
12
12
  export {
13
13
  GoogleMarketingRuntimeError,
14
14
  createGoogleMarketingCredentialStore,
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  IntelligenceService
3
- } from "./chunk-PXTSQ67Z.js";
4
- import "./chunk-EGGQSFQL.js";
3
+ } from "./chunk-XEWBDO5L.js";
4
+ import "./chunk-WGN2VT7L.js";
5
5
  export {
6
6
  IntelligenceService
7
7
  };
package/dist/mcp.js CHANGED
@@ -1,15 +1,15 @@
1
1
  import {
2
2
  autoSyncSkills
3
- } from "./chunk-U5JTZM66.js";
3
+ } from "./chunk-WFVK3XC7.js";
4
4
  import {
5
5
  CliError,
6
6
  PACKAGE_VERSION,
7
7
  canonryMcpTools,
8
8
  createApiClient
9
- } from "./chunk-YXDCVM5U.js";
9
+ } from "./chunk-BZDNTUCZ.js";
10
10
  import {
11
11
  isReadOnlyKey
12
- } from "./chunk-EGGQSFQL.js";
12
+ } from "./chunk-WGN2VT7L.js";
13
13
 
14
14
  // src/mcp/cli.ts
15
15
  import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@canonry/canonry",
3
- "version": "4.172.2",
3
+ "version": "4.172.3",
4
4
  "type": "module",
5
5
  "description": "Agent-first open-source AEO operating platform - track how answer engines cite your domain",
6
6
  "license": "FSL-1.1-ALv2",
@@ -71,29 +71,29 @@
71
71
  "tsup": "^8.5.1",
72
72
  "tsx": "^4.19.0",
73
73
  "@ainyc/canonry-api-client": "0.0.0",
74
- "@ainyc/canonry-api-routes": "0.0.0",
75
74
  "@ainyc/canonry-contracts": "0.0.0",
76
- "@ainyc/canonry-config": "0.0.0",
77
75
  "@ainyc/canonry-db": "0.0.0",
78
76
  "@ainyc/canonry-integration-bing": "0.0.0",
79
- "@ainyc/canonry-integration-cloud-run": "0.0.0",
80
- "@ainyc/canonry-integration-openai-ads": "0.0.0",
81
77
  "@ainyc/canonry-integration-cloudflare-queue": "0.0.0",
82
- "@ainyc/canonry-integration-commoncrawl": "0.0.0",
78
+ "@ainyc/canonry-api-routes": "0.0.0",
83
79
  "@ainyc/canonry-integration-cloudflare-worker": "0.0.0",
80
+ "@ainyc/canonry-integration-openai-ads": "0.0.0",
81
+ "@ainyc/canonry-integration-cloud-run": "0.0.0",
84
82
  "@ainyc/canonry-integration-google": "0.0.0",
83
+ "@ainyc/canonry-integration-commoncrawl": "0.0.0",
84
+ "@ainyc/canonry-integration-google-business-profile": "0.0.0",
85
85
  "@ainyc/canonry-integration-google-ads": "0.0.0",
86
+ "@ainyc/canonry-config": "0.0.0",
86
87
  "@ainyc/canonry-integration-google-places": "0.0.0",
87
- "@ainyc/canonry-integration-google-business-profile": "0.0.0",
88
88
  "@ainyc/canonry-integration-google-tag-manager": "0.0.0",
89
- "@ainyc/canonry-integration-wordpress": "0.0.0",
90
89
  "@ainyc/canonry-intelligence": "0.0.0",
91
90
  "@ainyc/canonry-integration-traffic": "0.0.0",
92
- "@ainyc/canonry-provider-local": "0.0.0",
93
- "@ainyc/canonry-provider-gemini": "0.0.0",
91
+ "@ainyc/canonry-integration-wordpress": "0.0.0",
94
92
  "@ainyc/canonry-provider-cdp": "0.0.0",
95
- "@ainyc/canonry-provider-openai": "0.0.0",
93
+ "@ainyc/canonry-provider-gemini": "0.0.0",
96
94
  "@ainyc/canonry-provider-claude": "0.0.0",
95
+ "@ainyc/canonry-provider-local": "0.0.0",
96
+ "@ainyc/canonry-provider-openai": "0.0.0",
97
97
  "@ainyc/canonry-provider-perplexity": "0.0.0"
98
98
  },
99
99
  "scripts": {