@canonry/canonry 4.178.4 → 4.179.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 (28) hide show
  1. package/assets/assets/{AuditHistoryPanel-BCtMrEMF.js → AuditHistoryPanel-lD6Q5KaA.js} +1 -1
  2. package/assets/assets/{BacklinksPage-CIo2hA0i.js → BacklinksPage-ClN1xbOa.js} +1 -1
  3. package/assets/assets/{ChartPrimitives-B_LDVvTy.js → ChartPrimitives-DG35TyhH.js} +1 -1
  4. package/assets/assets/{HistoryPage-D24U8cUG.js → HistoryPage-CXKCPfG7.js} +1 -1
  5. package/assets/assets/{MeasurementPropertyPage-BKDdv-jJ.js → MeasurementPropertyPage-CiJsa0If.js} +1 -1
  6. package/assets/assets/ProjectPage-CD0QbHPd.js +9 -0
  7. package/assets/assets/{RunRow-B39IK7hK.js → RunRow-DkFcHvDU.js} +1 -1
  8. package/assets/assets/{RunsPage-R4W1kD0B.js → RunsPage-CLzUDwTj.js} +1 -1
  9. package/assets/assets/{SettingsPage-BAOGyt1F.js → SettingsPage-0PRgB0gI.js} +1 -1
  10. package/assets/assets/{SiteHealthSection-Bx7yVNMQ.js → SiteHealthSection-BXAMjVeD.js} +3 -3
  11. package/assets/assets/{TrafficPage-DL8RvM2R.js → TrafficPage-CP4qsn82.js} +1 -1
  12. package/assets/assets/{TrafficSourceDetailPage-COzjakZa.js → TrafficSourceDetailPage-DoaIZ_ix.js} +1 -1
  13. package/assets/assets/{extract-error-message-B3TERCQ-.js → extract-error-message-Cn74-t3z.js} +1 -1
  14. package/assets/assets/{index-D0GbiVhZ.css → index-BD8hYPvq.css} +1 -1
  15. package/assets/assets/{index-xtxQtZRo.js → index-BR9BgNb3.js} +22 -22
  16. package/assets/assets/{react-sigma_core.esm.min-CbXAujub.js → react-sigma_core.esm.min-CZrBq6qL.js} +1 -1
  17. package/assets/index.html +2 -2
  18. package/dist/{chunk-KMK6AOB5.js → chunk-5BZWU35I.js} +145 -54
  19. package/dist/{chunk-IMEJQQZU.js → chunk-A2AB7UK5.js} +40 -2
  20. package/dist/{chunk-HNY2FNJH.js → chunk-FFXYNYPZ.js} +2 -2
  21. package/dist/{chunk-EBRGLDTB.js → chunk-LPUTKQDR.js} +2 -2
  22. package/dist/{chunk-WYCHM3EP.js → chunk-WG4EDZT3.js} +4 -4
  23. package/dist/cli.js +5 -5
  24. package/dist/index.js +4 -4
  25. package/dist/{intelligence-service-XPAKDZJI.js → intelligence-service-CKGM2RUJ.js} +2 -2
  26. package/dist/mcp.js +3 -3
  27. package/package.json +8 -8
  28. package/assets/assets/ProjectPage-DrIs_ZuR.js +0 -9
@@ -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-Bx7yVNMQ.js";import"./index-xtxQtZRo.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-B_LDVvTy.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-BXAMjVeD.js";import"./index-BR9BgNb3.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-DG35TyhH.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,14 +12,14 @@
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-xtxQtZRo.js"></script>
15
+ <script type="module" crossorigin src="./assets/index-BR9BgNb3.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">
19
19
  <link rel="modulepreload" crossorigin href="./assets/vendor-lucide-nYKv-BB7.js">
20
20
  <link rel="modulepreload" crossorigin href="./assets/vendor-markdown-Bn7fRwrx.js">
21
21
  <link rel="modulepreload" crossorigin href="./assets/vendor-yaml-GWJz5H2G.js">
22
- <link rel="stylesheet" crossorigin href="./assets/index-D0GbiVhZ.css">
22
+ <link rel="stylesheet" crossorigin href="./assets/index-BD8hYPvq.css">
23
23
  </head>
24
24
  <body>
25
25
  <div id="root"></div>
@@ -113,6 +113,7 @@ import {
113
113
  TrafficEventConfidences,
114
114
  TrafficEventKinds,
115
115
  TrafficEvidenceKinds,
116
+ TrafficPathClasses,
116
117
  TrafficSeriesGranularities,
117
118
  TrafficSourceAuthModes,
118
119
  TrafficSourceStatuses,
@@ -638,10 +639,10 @@ import {
638
639
  wordpressSchemaDeployResultDtoSchema,
639
640
  wordpressSchemaStatusResultDtoSchema,
640
641
  wordpressStatusDtoSchema
641
- } from "./chunk-IMEJQQZU.js";
642
+ } from "./chunk-A2AB7UK5.js";
642
643
 
643
644
  // src/intelligence-service.ts
644
- import { eq as eq62, desc as desc27, asc as asc11, and as and51, ne as ne8, or as or14, inArray as inArray21, gte as gte14, lte as lte12, isNull as isNull9, sql as sql25, exists } from "drizzle-orm";
645
+ import { eq as eq62, desc as desc27, asc as asc11, and as and51, ne as ne8, or as or14, inArray as inArray22, gte as gte14, lte as lte12, isNull as isNull9, sql as sql25, exists } from "drizzle-orm";
645
646
 
646
647
  // ../db/src/client.ts
647
648
  import { mkdirSync } from "fs";
@@ -20869,6 +20870,7 @@ async function applyRoutes(app, opts) {
20869
20870
  }
20870
20871
  const now = (/* @__PURE__ */ new Date()).toISOString();
20871
20872
  const name = config.metadata.name;
20873
+ const managesQueries = "queries" in rawSpec || "keywords" in rawSpec;
20872
20874
  const configQueries = resolveConfigSpecQueries(config.spec);
20873
20875
  const target = app.db.select({ id: projects.id, providerModels: projects.providerModels }).from(projects).where(eq22(projects.name, name)).get();
20874
20876
  const scopedProjectId = request.apiKey?.projectId;
@@ -20947,14 +20949,16 @@ async function applyRoutes(app, opts) {
20947
20949
  entityId: projectId
20948
20950
  });
20949
20951
  }
20950
- replaceProjectQueries(tx, projectId, configQueries, now);
20951
- writeAuditLog(tx, {
20952
- projectId,
20953
- actor: "api",
20954
- action: "queries.replaced",
20955
- entityType: "query",
20956
- diff: { queries: configQueries }
20957
- });
20952
+ if (managesQueries) {
20953
+ replaceProjectQueries(tx, projectId, configQueries, now);
20954
+ writeAuditLog(tx, {
20955
+ projectId,
20956
+ actor: "api",
20957
+ action: "queries.replaced",
20958
+ entityType: "query",
20959
+ diff: { queries: configQueries }
20960
+ });
20961
+ }
20958
20962
  tx.delete(competitors).where(eq22(competitors.projectId, projectId)).run();
20959
20963
  const normalizedCompetitors = normalizeCompetitorList2(config.spec.competitors);
20960
20964
  for (const domain of normalizedCompetitors) {
@@ -52687,7 +52691,7 @@ import crypto43 from "crypto";
52687
52691
  import { isIP } from "net";
52688
52692
  import { isDeepStrictEqual } from "util";
52689
52693
  import { Agent as UndiciAgent } from "undici";
52690
- import { and as and44, desc as desc23, eq as eq51, gte as gte11, lte as lte11, sql as sql22 } from "drizzle-orm";
52694
+ import { and as and44, desc as desc23, eq as eq51, gte as gte11, inArray as inArray18, lte as lte11, sql as sql22 } from "drizzle-orm";
52691
52695
 
52692
52696
  // ../api-routes/src/cloudflare-worker-version.ts
52693
52697
  var CURRENT_CLOUDFLARE_WORKER_VERSION = "1.0.1";
@@ -69817,7 +69821,7 @@ function assertCloudflareIngestUrlOutsideWorkerRoute(ingestUrl, workerRouteHost)
69817
69821
  }
69818
69822
  }
69819
69823
  function emptyTrafficSeriesPoint(bucket) {
69820
- return { bucket, crawlerHits: 0, aiUserFetchHits: 0, aiReferralHits: 0, aiReferralLandedHits: 0 };
69824
+ return { bucket, crawlerHits: 0, aiUserFetchHits: 0, aiReferralHits: 0, aiReferralLandedHits: 0, crawlerContentHits: 0, measured: true };
69821
69825
  }
69822
69826
  function completeTrafficSeries(windowStart, windowEnd, granularity, pointsByBucket) {
69823
69827
  const cursor = new Date(windowStart);
@@ -72467,6 +72471,11 @@ async function trafficRoutes(app, opts) {
72467
72471
  const project = resolveProject(app.db, request.params.name);
72468
72472
  const now = /* @__PURE__ */ new Date();
72469
72473
  const defaultSince = new Date(now.getTime() - 24 * 60 * 6e4);
72474
+ if (request.query?.sinceMinutes !== void 0) {
72475
+ throw validationError(
72476
+ '"sinceMinutes" is not a query parameter on this route. Use "since" (and optionally "until") with an ISO-8601 timestamp.'
72477
+ );
72478
+ }
72470
72479
  const sinceParam = request.query?.since;
72471
72480
  const untilParam = request.query?.until;
72472
72481
  const since = sinceParam ? new Date(sinceParam) : defaultSince;
@@ -72540,12 +72549,43 @@ async function trafficRoutes(app, opts) {
72540
72549
  crawlerTotal = crawlerSegments.content + crawlerSegments.sitemap + crawlerSegments.robots + crawlerSegments.asset + crawlerSegments.other;
72541
72550
  totalEventRows += pathTotals.reduce((sum, row) => sum + Number(row.rows), 0);
72542
72551
  const crawlerSeriesBucket = granularity === TrafficSeriesGranularities.day ? sql22`substr(${crawlerEventsHourly.tsHour}, 1, 10)` : crawlerEventsHourly.tsHour;
72543
- const crawlerSeries = app.db.select({
72544
- bucket: crawlerSeriesBucket,
72545
- hits: sql22`COALESCE(SUM(${crawlerEventsHourly.hits}), 0)`
72546
- }).from(crawlerEventsHourly).where(crawlerWhere).groupBy(crawlerSeriesBucket).all();
72547
- for (const row of crawlerSeries) {
72548
- trafficSeriesPoint(seriesByBucket, row.bucket).crawlerHits = Number(row.hits);
72552
+ const distinctPaths = pathTotals.map((r) => ({ pathNormalized: r.pathNormalized }));
72553
+ const contentPaths = [];
72554
+ const infraPaths = [];
72555
+ for (const { pathNormalized } of distinctPaths) {
72556
+ if (classifyTrafficPath(pathNormalized) === TrafficPathClasses.content) contentPaths.push(pathNormalized);
72557
+ else infraPaths.push(pathNormalized);
72558
+ }
72559
+ const useContentList = contentPaths.length <= infraPaths.length;
72560
+ const listed = useContentList ? contentPaths : infraPaths;
72561
+ const IN_LIST_CAP = 2e4;
72562
+ const listFitsInSql = listed.length <= IN_LIST_CAP;
72563
+ const contentExpr = listed.length === 0 ? useContentList ? sql22`0` : sql22`${crawlerEventsHourly.hits}` : useContentList ? sql22`CASE WHEN ${inArray18(crawlerEventsHourly.pathNormalized, listed)} THEN ${crawlerEventsHourly.hits} ELSE 0 END` : sql22`CASE WHEN ${inArray18(crawlerEventsHourly.pathNormalized, listed)} THEN 0 ELSE ${crawlerEventsHourly.hits} END`;
72564
+ if (listFitsInSql) {
72565
+ const crawlerSeries = app.db.select({
72566
+ bucket: crawlerSeriesBucket,
72567
+ hits: sql22`COALESCE(SUM(${crawlerEventsHourly.hits}), 0)`,
72568
+ content: sql22`COALESCE(SUM(${contentExpr}), 0)`
72569
+ }).from(crawlerEventsHourly).where(crawlerWhere).groupBy(crawlerSeriesBucket).all();
72570
+ for (const row of crawlerSeries) {
72571
+ const point = trafficSeriesPoint(seriesByBucket, String(row.bucket));
72572
+ point.crawlerHits = Number(row.hits);
72573
+ point.crawlerContentHits = Number(row.content);
72574
+ }
72575
+ } else {
72576
+ const contentSet = new Set(useContentList ? contentPaths : infraPaths);
72577
+ const grouped = app.db.select({
72578
+ bucket: crawlerSeriesBucket,
72579
+ pathNormalized: crawlerEventsHourly.pathNormalized,
72580
+ hits: sql22`COALESCE(SUM(${crawlerEventsHourly.hits}), 0)`
72581
+ }).from(crawlerEventsHourly).where(crawlerWhere).groupBy(crawlerSeriesBucket, crawlerEventsHourly.pathNormalized).all();
72582
+ for (const row of grouped) {
72583
+ const point = trafficSeriesPoint(seriesByBucket, String(row.bucket));
72584
+ const hits = Number(row.hits);
72585
+ point.crawlerHits += hits;
72586
+ const inList = contentSet.has(row.pathNormalized);
72587
+ if (useContentList ? inList : !inList) point.crawlerContentHits += hits;
72588
+ }
72549
72589
  }
72550
72590
  const rows = app.db.select().from(crawlerEventsHourly).where(crawlerWhere).orderBy(desc23(crawlerEventsHourly.tsHour)).limit(limit).all();
72551
72591
  for (const r of rows) {
@@ -72684,10 +72724,61 @@ async function trafficRoutes(app, opts) {
72684
72724
  const response = {
72685
72725
  windowStart: sinceIso,
72686
72726
  windowEnd: untilIso,
72687
- series: {
72688
- granularity,
72689
- points: completeTrafficSeries(since, until, granularity, seriesByBucket)
72690
- },
72727
+ series: (() => {
72728
+ const points = completeTrafficSeries(since, until, granularity, seriesByBucket);
72729
+ const coverageScope = (col, srcCol) => sourceIdParam ? and44(eq51(col, project.id), eq51(srcCol, sourceIdParam)) : eq51(col, project.id);
72730
+ const firsts = [
72731
+ app.db.select({ v: sql22`MIN(${crawlerEventsHourly.tsHour})` }).from(crawlerEventsHourly).where(coverageScope(crawlerEventsHourly.projectId, crawlerEventsHourly.sourceId)).get()?.v,
72732
+ app.db.select({ v: sql22`MIN(${aiUserFetchEventsHourly.tsHour})` }).from(aiUserFetchEventsHourly).where(coverageScope(aiUserFetchEventsHourly.projectId, aiUserFetchEventsHourly.sourceId)).get()?.v,
72733
+ app.db.select({ v: sql22`MIN(${aiReferralEventsHourly.tsHour})` }).from(aiReferralEventsHourly).where(coverageScope(aiReferralEventsHourly.projectId, aiReferralEventsHourly.sourceId)).get()?.v
72734
+ ].filter((v) => typeof v === "string" && v.length > 0);
72735
+ const coverageStart = firsts.length ? firsts.slice().sort()[0] : null;
72736
+ const bucketStartMs = (bucket) => Date.parse(
72737
+ granularity === TrafficSeriesGranularities.day ? `${bucket}T00:00:00.000Z` : bucket
72738
+ );
72739
+ const bucketMs = granularity === TrafficSeriesGranularities.day ? 864e5 : 36e5;
72740
+ const lastBucket = points.length ? points[points.length - 1].bucket : null;
72741
+ const lastBucketStartMs = lastBucket === null ? null : bucketStartMs(lastBucket);
72742
+ const trailingBucketIsPartial = lastBucketStartMs !== null && Number.isFinite(lastBucketStartMs) && until.getTime() < lastBucketStartMs + bucketMs;
72743
+ const coverageKey = coverageStart === null ? null : granularity === TrafficSeriesGranularities.day ? coverageStart.slice(0, 10) : coverageStart.slice(0, 13);
72744
+ for (const pt of points) {
72745
+ pt.measured = coverageKey === null ? false : (granularity === TrafficSeriesGranularities.day ? pt.bucket.slice(0, 10) : pt.bucket.slice(0, 13)) >= coverageKey;
72746
+ }
72747
+ const firstMeasuredIdx = points.findIndex((pt) => pt.measured);
72748
+ const coverageStartMs = coverageStart === null ? null : Date.parse(coverageStart);
72749
+ const leadingBucketIsPartial = firstMeasuredIdx >= 0 && coverageStartMs !== null && Number.isFinite(coverageStartMs) && coverageStartMs > bucketStartMs(points[firstMeasuredIdx].bucket);
72750
+ return {
72751
+ granularity,
72752
+ points,
72753
+ coverageStart,
72754
+ // Two edges are excluded from the fit, both for the same reason: a
72755
+ // bucket that is not a full reading must not be treated as one.
72756
+ //
72757
+ // Leading: unmeasured buckets predate recording, so they are the
72758
+ // ABSENCE of a reading, not a reading of zero. The first MEASURED
72759
+ // bucket goes too when recording began inside it, since a fraction of
72760
+ // a bucket read as a whole one slopes the fit up out of nothing.
72761
+ //
72762
+ // Trailing: `until` defaults to now, so the newest bucket holds only
72763
+ // the elapsed fraction of the current period. A site flat at 500/day
72764
+ // read at 02:00 UTC gives [...500, 500, 40] and the fit returns a
72765
+ // confident decline for a site that is not declining. Same class of
72766
+ // error as the leading edge, and the one the leading guard alone
72767
+ // would have left in place.
72768
+ //
72769
+ // linearTrend skips nulls while surviving points keep their true
72770
+ // index, so dropping an edge does not compress the x-axis.
72771
+ trends: (() => {
72772
+ const usable = (pt, i) => pt.measured && !(i === firstMeasuredIdx && leadingBucketIsPartial) && !(i === points.length - 1 && trailingBucketIsPartial);
72773
+ const series = (pick) => linearTrend(points.map((pt, i) => usable(pt, i) ? pick(pt) : null));
72774
+ return {
72775
+ crawlerContentHits: series((pt) => pt.crawlerContentHits),
72776
+ aiUserFetchHits: series((pt) => pt.aiUserFetchHits),
72777
+ aiReferralLandedHits: series((pt) => pt.aiReferralLandedHits)
72778
+ };
72779
+ })()
72780
+ };
72781
+ })(),
72691
72782
  totals: {
72692
72783
  crawlerHits: crawlerTotal,
72693
72784
  crawlerContentHits: crawlerSegments.content,
@@ -74445,7 +74536,7 @@ var RUNTIME_STATE_CHECKS = [
74445
74536
  ];
74446
74537
 
74447
74538
  // ../api-routes/src/doctor/checks/traffic-source.ts
74448
- import { and as and47, eq as eq57, gte as gte12, inArray as inArray18, ne as ne7, sql as sql23 } from "drizzle-orm";
74539
+ import { and as and47, eq as eq57, gte as gte12, inArray as inArray19, ne as ne7, sql as sql23 } from "drizzle-orm";
74449
74540
  var RECENT_DATA_WARN_DAYS = 7;
74450
74541
  var RECENT_DATA_FAIL_DAYS = 30;
74451
74542
  function isCloudflareDirectPush(source) {
@@ -74593,7 +74684,7 @@ var recentDataCheck = {
74593
74684
  ctx.db.select({ total: sql23`COALESCE(SUM(${crawlerEventsHourly.hits}), 0)` }).from(crawlerEventsHourly).where(
74594
74685
  and47(
74595
74686
  eq57(crawlerEventsHourly.projectId, ctx.project.id),
74596
- inArray18(crawlerEventsHourly.sourceId, activeSourceIds),
74687
+ inArray19(crawlerEventsHourly.sourceId, activeSourceIds),
74597
74688
  gte12(crawlerEventsHourly.tsHour, warnCutoff)
74598
74689
  )
74599
74690
  ).get()?.total ?? 0
@@ -74602,7 +74693,7 @@ var recentDataCheck = {
74602
74693
  ctx.db.select({ total: sql23`COALESCE(SUM(${aiReferralEventsHourly.sessionsOrHits}), 0)` }).from(aiReferralEventsHourly).where(
74603
74694
  and47(
74604
74695
  eq57(aiReferralEventsHourly.projectId, ctx.project.id),
74605
- inArray18(aiReferralEventsHourly.sourceId, activeSourceIds),
74696
+ inArray19(aiReferralEventsHourly.sourceId, activeSourceIds),
74606
74697
  gte12(aiReferralEventsHourly.tsHour, warnCutoff)
74607
74698
  )
74608
74699
  ).get()?.total ?? 0
@@ -74611,7 +74702,7 @@ var recentDataCheck = {
74611
74702
  ctx.db.select({ total: sql23`COALESCE(SUM(${aiUserFetchEventsHourly.hits}), 0)` }).from(aiUserFetchEventsHourly).where(
74612
74703
  and47(
74613
74704
  eq57(aiUserFetchEventsHourly.projectId, ctx.project.id),
74614
- inArray18(aiUserFetchEventsHourly.sourceId, activeSourceIds),
74705
+ inArray19(aiUserFetchEventsHourly.sourceId, activeSourceIds),
74615
74706
  gte12(aiUserFetchEventsHourly.tsHour, warnCutoff)
74616
74707
  )
74617
74708
  ).get()?.total ?? 0
@@ -74637,7 +74728,7 @@ var recentDataCheck = {
74637
74728
  ctx.db.select({ total: sql23`COALESCE(SUM(${crawlerEventsHourly.hits}), 0)` }).from(crawlerEventsHourly).where(
74638
74729
  and47(
74639
74730
  eq57(crawlerEventsHourly.projectId, ctx.project.id),
74640
- inArray18(crawlerEventsHourly.sourceId, activeSourceIds),
74731
+ inArray19(crawlerEventsHourly.sourceId, activeSourceIds),
74641
74732
  gte12(crawlerEventsHourly.tsHour, failCutoff)
74642
74733
  )
74643
74734
  ).get()?.total ?? 0
@@ -74646,7 +74737,7 @@ var recentDataCheck = {
74646
74737
  ctx.db.select({ total: sql23`COALESCE(SUM(${aiReferralEventsHourly.sessionsOrHits}), 0)` }).from(aiReferralEventsHourly).where(
74647
74738
  and47(
74648
74739
  eq57(aiReferralEventsHourly.projectId, ctx.project.id),
74649
- inArray18(aiReferralEventsHourly.sourceId, activeSourceIds),
74740
+ inArray19(aiReferralEventsHourly.sourceId, activeSourceIds),
74650
74741
  gte12(aiReferralEventsHourly.tsHour, failCutoff)
74651
74742
  )
74652
74743
  ).get()?.total ?? 0
@@ -74655,7 +74746,7 @@ var recentDataCheck = {
74655
74746
  ctx.db.select({ total: sql23`COALESCE(SUM(${aiUserFetchEventsHourly.hits}), 0)` }).from(aiUserFetchEventsHourly).where(
74656
74747
  and47(
74657
74748
  eq57(aiUserFetchEventsHourly.projectId, ctx.project.id),
74658
- inArray18(aiUserFetchEventsHourly.sourceId, activeSourceIds),
74749
+ inArray19(aiUserFetchEventsHourly.sourceId, activeSourceIds),
74659
74750
  gte12(aiUserFetchEventsHourly.tsHour, failCutoff)
74660
74751
  )
74661
74752
  ).get()?.total ?? 0
@@ -75571,7 +75662,7 @@ async function doctorRoutes(app, opts) {
75571
75662
 
75572
75663
  // ../api-routes/src/discovery/routes.ts
75573
75664
  import crypto45 from "crypto";
75574
- import { and as and48, desc as desc24, eq as eq58, gte as gte13, inArray as inArray19, isNull as isNull7, or as or12 } from "drizzle-orm";
75665
+ import { and as and48, desc as desc24, eq as eq58, gte as gte13, inArray as inArray20, isNull as isNull7, or as or12 } from "drizzle-orm";
75575
75666
  var MAX_INFLIGHT_DISCOVERY_AGE_MS = 2 * 60 * 60 * 1e3;
75576
75667
  async function discoveryRoutes(app, opts) {
75577
75668
  app.post("/projects/:name/discover/run", async (request, reply) => {
@@ -75626,7 +75717,7 @@ async function discoveryRoutes(app, opts) {
75626
75717
  // must never reuse another set's session. Null (= Gemini-only
75627
75718
  // default, including explicit ['gemini']) matches legacy rows.
75628
75719
  seedProviders == null ? isNull7(discoverySessions.seedProviders) : eq58(discoverySessions.seedProviders, seedProviders),
75629
- inArray19(discoverySessions.status, [
75720
+ inArray20(discoverySessions.status, [
75630
75721
  DiscoverySessionStatuses.queued,
75631
75722
  DiscoverySessionStatuses.seeding,
75632
75723
  DiscoverySessionStatuses.probing
@@ -76251,7 +76342,7 @@ function dedupeStrings(input) {
76251
76342
 
76252
76343
  // ../api-routes/src/technical-aeo.ts
76253
76344
  import crypto47 from "crypto";
76254
- import { and as and49, asc as asc10, count, desc as desc25, eq as eq60, inArray as inArray20, isNotNull as isNotNull3, isNull as isNull8, lt as lt11, or as or13, sql as sql24 } from "drizzle-orm";
76345
+ import { and as and49, asc as asc10, count, desc as desc25, eq as eq60, inArray as inArray21, isNotNull as isNotNull3, isNull as isNull8, lt as lt11, or as or13, sql as sql24 } from "drizzle-orm";
76255
76346
  import { alias } from "drizzle-orm/sqlite-core";
76256
76347
  var FETCHED_SITE_CRAWL_STATES = /* @__PURE__ */ new Set([
76257
76348
  ...SiteCrawlFetchedStates,
@@ -76573,7 +76664,7 @@ async function technicalAeoRoutes(app, opts) {
76573
76664
  eq60(siteCrawlSnapshots.projectId, projectId),
76574
76665
  eq60(runs.projectId, projectId),
76575
76666
  eq60(runs.kind, RunKinds["site-audit"]),
76576
- inArray20(runs.status, SURFACEABLE_STATUSES),
76667
+ inArray21(runs.status, SURFACEABLE_STATUSES),
76577
76668
  notProbeRun()
76578
76669
  ];
76579
76670
  if (runId) {
@@ -76603,7 +76694,7 @@ async function technicalAeoRoutes(app, opts) {
76603
76694
  eq60(runs.id, runId),
76604
76695
  eq60(runs.projectId, projectId),
76605
76696
  eq60(runs.kind, RunKinds["site-audit"]),
76606
- inArray20(runs.status, SURFACEABLE_STATUSES),
76697
+ inArray21(runs.status, SURFACEABLE_STATUSES),
76607
76698
  notProbeRun()
76608
76699
  )).limit(1).get());
76609
76700
  const assertKnownAuditRun = (projectId, runId) => {
@@ -76613,7 +76704,7 @@ async function technicalAeoRoutes(app, opts) {
76613
76704
  eq60(siteAuditSnapshots.projectId, projectId),
76614
76705
  eq60(runs.projectId, projectId),
76615
76706
  eq60(runs.kind, RunKinds["site-audit"]),
76616
- inArray20(runs.status, SURFACEABLE_STATUSES),
76707
+ inArray21(runs.status, SURFACEABLE_STATUSES),
76617
76708
  notProbeRun()
76618
76709
  )).limit(1).get());
76619
76710
  const emptyCrawlSummary = (projectName, legacyAuditAvailable) => ({
@@ -76637,7 +76728,7 @@ async function technicalAeoRoutes(app, opts) {
76637
76728
  eq60(siteAuditSnapshots.projectId, project.id),
76638
76729
  eq60(runs.projectId, project.id),
76639
76730
  eq60(runs.kind, RunKinds["site-audit"]),
76640
- inArray20(runs.status, SURFACEABLE_STATUSES),
76731
+ inArray21(runs.status, SURFACEABLE_STATUSES),
76641
76732
  notProbeRun()
76642
76733
  ];
76643
76734
  const targetFilters = request.query.runId ? [...baseFilters, eq60(siteAuditSnapshots.runId, request.query.runId)] : baseFilters;
@@ -76677,7 +76768,7 @@ async function technicalAeoRoutes(app, opts) {
76677
76768
  eq60(siteAuditSnapshots.projectId, project.id),
76678
76769
  eq60(runs.projectId, project.id),
76679
76770
  eq60(runs.kind, RunKinds["site-audit"]),
76680
- inArray20(runs.status, SURFACEABLE_STATUSES),
76771
+ inArray21(runs.status, SURFACEABLE_STATUSES),
76681
76772
  notProbeRun()
76682
76773
  ];
76683
76774
  if (request.query.runId) targetFilters.push(eq60(siteAuditSnapshots.runId, request.query.runId));
@@ -76719,7 +76810,7 @@ async function technicalAeoRoutes(app, opts) {
76719
76810
  eq60(siteAuditSnapshots.projectId, project.id),
76720
76811
  eq60(runs.projectId, project.id),
76721
76812
  eq60(runs.kind, RunKinds["site-audit"]),
76722
- inArray20(runs.status, SURFACEABLE_STATUSES),
76813
+ inArray21(runs.status, SURFACEABLE_STATUSES),
76723
76814
  notProbeRun()
76724
76815
  )).orderBy(desc25(siteAuditSnapshots.createdAt)).limit(limit).all();
76725
76816
  return { project: project.name, points: rows.reverse() };
@@ -77022,8 +77113,8 @@ async function technicalAeoRoutes(app, opts) {
77022
77113
  eq60(siteCrawlEdges.internal, true),
77023
77114
  isNotNull3(siteCrawlEdges.targetNodeKey),
77024
77115
  or13(
77025
- inArray20(siteCrawlEdges.sourceNodeKey, frontier),
77026
- inArray20(siteCrawlEdges.targetNodeKey, frontier)
77116
+ inArray21(siteCrawlEdges.sourceNodeKey, frontier),
77117
+ inArray21(siteCrawlEdges.targetNodeKey, frontier)
77027
77118
  )
77028
77119
  )).orderBy(asc10(siteCrawlEdges.edgeKey)).limit(maxEdges + maxNodes + 1).all();
77029
77120
  if (candidates.length > maxEdges + maxNodes) queryTruncated = true;
@@ -77060,7 +77151,7 @@ async function technicalAeoRoutes(app, opts) {
77060
77151
  eq60(siteCrawlPages.projectId, scope.projectId),
77061
77152
  eq60(siteCrawlPages.runId, scope.runId),
77062
77153
  eq60(siteCrawlPages.attemptId, scope.attemptId),
77063
- inArray20(siteCrawlPages.nodeKey, nodeKeys)
77154
+ inArray21(siteCrawlPages.nodeKey, nodeKeys)
77064
77155
  )).all();
77065
77156
  const persistedNodeKeys = new Set(pageRows.map((row) => row.nodeKey));
77066
77157
  const outermostNodeKeys = pageRows.filter((row) => distances.get(row.nodeKey) === hops).map((row) => row.nodeKey);
@@ -77070,8 +77161,8 @@ async function technicalAeoRoutes(app, opts) {
77070
77161
  eq60(siteCrawlEdges.attemptId, scope.attemptId),
77071
77162
  eq60(siteCrawlEdges.internal, true),
77072
77163
  isNotNull3(siteCrawlEdges.targetNodeKey),
77073
- inArray20(siteCrawlEdges.sourceNodeKey, outermostNodeKeys),
77074
- inArray20(siteCrawlEdges.targetNodeKey, outermostNodeKeys)
77164
+ inArray21(siteCrawlEdges.sourceNodeKey, outermostNodeKeys),
77165
+ inArray21(siteCrawlEdges.targetNodeKey, outermostNodeKeys)
77075
77166
  )).limit(1).get();
77076
77167
  if (omittedOutermostEdge && !seenEdgeKeys.has(omittedOutermostEdge.edgeKey)) {
77077
77168
  omittedEdgeKeys.add(omittedOutermostEdge.edgeKey);
@@ -77174,7 +77265,7 @@ async function technicalAeoRoutes(app, opts) {
77174
77265
  eq60(siteCrawlEdges.followable, true),
77175
77266
  eq60(siteCrawlEdges.relation, "anchor"),
77176
77267
  isNotNull3(siteCrawlEdges.targetNodeKey),
77177
- inArray20(siteCrawlEdges.sourceNodeKey, frontier)
77268
+ inArray21(siteCrawlEdges.sourceNodeKey, frontier)
77178
77269
  )).orderBy(asc10(siteCrawlEdges.edgeKey)).limit(SITE_HEALTH_PATH_MAX_VISITED_NODES + 1).all();
77179
77270
  if (candidates.length > SITE_HEALTH_PATH_MAX_VISITED_NODES) truncated = true;
77180
77271
  const candidateTargetKeys = [...new Set(candidates.map((edge) => edge.targetNodeKey).filter((nodeKey) => nodeKey != null))];
@@ -77182,7 +77273,7 @@ async function technicalAeoRoutes(app, opts) {
77182
77273
  eq60(siteCrawlPages.projectId, scope.projectId),
77183
77274
  eq60(siteCrawlPages.runId, scope.runId),
77184
77275
  eq60(siteCrawlPages.attemptId, scope.attemptId),
77185
- inArray20(siteCrawlPages.nodeKey, candidateTargetKeys)
77276
+ inArray21(siteCrawlPages.nodeKey, candidateTargetKeys)
77186
77277
  )).all().map((row) => row.nodeKey));
77187
77278
  const next = /* @__PURE__ */ new Set();
77188
77279
  for (const edge of candidates.slice(0, SITE_HEALTH_PATH_MAX_VISITED_NODES)) {
@@ -77228,7 +77319,7 @@ async function technicalAeoRoutes(app, opts) {
77228
77319
  eq60(siteCrawlPages.projectId, scope.projectId),
77229
77320
  eq60(siteCrawlPages.runId, scope.runId),
77230
77321
  eq60(siteCrawlPages.attemptId, scope.attemptId),
77231
- inArray20(siteCrawlPages.nodeKey, pathKeys)
77322
+ inArray21(siteCrawlPages.nodeKey, pathKeys)
77232
77323
  )).all();
77233
77324
  const pageByKey = new Map(pathRows.map((row) => [row.nodeKey, row]));
77234
77325
  const pathDetection = templateDetectionOf(snapshot.templateDetection);
@@ -77510,14 +77601,14 @@ async function technicalAeoRoutes(app, opts) {
77510
77601
  eq60(siteCrawlPages.projectId, scope.projectId),
77511
77602
  eq60(siteCrawlPages.runId, scope.runId),
77512
77603
  eq60(siteCrawlPages.attemptId, scope.attemptId),
77513
- inArray20(siteCrawlPages.nodeKey, pageKeys)
77604
+ inArray21(siteCrawlPages.nodeKey, pageKeys)
77514
77605
  )).all();
77515
77606
  const edgeRowsFor = (scope) => linkKeys.length === 0 ? [] : app.db.select().from(siteCrawlEdges).where(and49(
77516
77607
  eq60(siteCrawlEdges.projectId, scope.projectId),
77517
77608
  eq60(siteCrawlEdges.runId, scope.runId),
77518
77609
  eq60(siteCrawlEdges.attemptId, scope.attemptId),
77519
77610
  eq60(siteCrawlEdges.internal, true),
77520
- inArray20(siteCrawlEdges.edgeKey, linkKeys)
77611
+ inArray21(siteCrawlEdges.edgeKey, linkKeys)
77521
77612
  )).all();
77522
77613
  const beforePages = new Map(pageRowsFor(beforeScope).map((row) => [row.nodeKey, mapCrawlPage(row)]));
77523
77614
  const afterPages = new Map(pageRowsFor(afterScope).map((row) => [row.nodeKey, mapCrawlPage(row)]));
@@ -77965,9 +78056,9 @@ async function technicalAeoRoutes(app, opts) {
77965
78056
  eq60(siteCrawlSnapshots.projectId, project.id),
77966
78057
  eq60(runs.projectId, project.id),
77967
78058
  eq60(runs.kind, RunKinds["site-audit"]),
77968
- inArray20(runs.status, SURFACEABLE_STATUSES),
78059
+ inArray21(runs.status, SURFACEABLE_STATUSES),
77969
78060
  notProbeRun(),
77970
- inArray20(siteCrawlSnapshots.runId, runIds)
78061
+ inArray21(siteCrawlSnapshots.runId, runIds)
77971
78062
  )).all().map((row) => row.runId));
77972
78063
  return {
77973
78064
  project: project.name,
@@ -78107,7 +78198,7 @@ async function technicalAeoRoutes(app, opts) {
78107
78198
  )).where(and49(
78108
78199
  eq60(runs.projectId, project.id),
78109
78200
  eq60(runs.kind, RunKinds["site-audit"]),
78110
- inArray20(runs.status, [RunStatuses.queued, RunStatuses.running])
78201
+ inArray21(runs.status, [RunStatuses.queued, RunStatuses.running])
78111
78202
  )).get();
78112
78203
  if (existing) {
78113
78204
  if (existing.identityKey === identityKey) {
@@ -79311,7 +79402,7 @@ var IntelligenceService = class {
79311
79402
  let wouldDeleteTotal = 0;
79312
79403
  const existingByRunId = /* @__PURE__ */ new Map();
79313
79404
  if (isDryRun && targetRuns.length > 0) {
79314
- const rows = this.db.select({ runId: insights.runId }).from(insights).where(inArray21(insights.runId, targetRuns.map((r) => r.id))).all();
79405
+ const rows = this.db.select({ runId: insights.runId }).from(insights).where(inArray22(insights.runId, targetRuns.map((r) => r.id))).all();
79315
79406
  for (const r of rows) {
79316
79407
  if (r.runId == null) continue;
79317
79408
  existingByRunId.set(r.runId, (existingByRunId.get(r.runId) ?? 0) + 1);
@@ -79366,7 +79457,7 @@ var IntelligenceService = class {
79366
79457
  */
79367
79458
  runIdsWithSnapshots(runIds) {
79368
79459
  if (runIds.length === 0) return /* @__PURE__ */ new Set();
79369
- const rows = this.db.select({ runId: querySnapshots.runId }).from(querySnapshots).where(inArray21(querySnapshots.runId, [...runIds])).groupBy(querySnapshots.runId).all();
79460
+ const rows = this.db.select({ runId: querySnapshots.runId }).from(querySnapshots).where(inArray22(querySnapshots.runId, [...runIds])).groupBy(querySnapshots.runId).all();
79370
79461
  return new Set(rows.map((r) => r.runId));
79371
79462
  }
79372
79463
  /**
@@ -79486,7 +79577,7 @@ var IntelligenceService = class {
79486
79577
  const haveHistory = recentRunIds.length > 0;
79487
79578
  const priorRegressionsByPair = /* @__PURE__ */ new Map();
79488
79579
  if (haveHistory) {
79489
- const priorRows = this.db.select({ query: insights.query, provider: insights.provider, runId: insights.runId }).from(insights).where(and51(eq62(insights.type, "regression"), inArray21(insights.runId, recentRunIds))).all();
79580
+ const priorRows = this.db.select({ query: insights.query, provider: insights.provider, runId: insights.runId }).from(insights).where(and51(eq62(insights.type, "regression"), inArray22(insights.runId, recentRunIds))).all();
79490
79581
  const regressionGroups = /* @__PURE__ */ new Map();
79491
79582
  for (const row of priorRows) {
79492
79583
  if (!row.runId) continue;
@@ -14749,7 +14749,22 @@ var trafficSeriesPointSchema = z50.object({
14749
14749
  * The part of `aiReferralHits` not answered with a Location redirect — the
14750
14750
  * series to chart under any label that says sessions or visits.
14751
14751
  */
14752
- aiReferralLandedHits: z50.number().int().nonnegative()
14752
+ aiReferralLandedHits: z50.number().int().nonnegative(),
14753
+ /**
14754
+ * The part of `crawlerHits` that is a real content page, excluding robots,
14755
+ * sitemaps and assets. `crawlerHits` keeps its full-count contract; this is
14756
+ * the series to chart under any label that says "pages crawled", because a
14757
+ * sitemap re-fetch is not a page an engine read.
14758
+ */
14759
+ crawlerContentHits: z50.number().int().nonnegative(),
14760
+ /**
14761
+ * False for a bucket that predates any observation for this project, i.e.
14762
+ * before `series.coverageStart`. Such a bucket reads 0 because nothing was
14763
+ * being recorded, NOT because nothing happened, and a chart must not draw
14764
+ * those as a measured zero. Derived here rather than in a component so the
14765
+ * CLI draws the same distinction.
14766
+ */
14767
+ measured: z50.boolean()
14753
14768
  });
14754
14769
  var trafficCrawlerEventEntrySchema = z50.object({
14755
14770
  kind: z50.literal(TrafficEventKinds.crawler),
@@ -14816,7 +14831,29 @@ var trafficEventsResponseSchema = z50.object({
14816
14831
  */
14817
14832
  series: z50.object({
14818
14833
  granularity: trafficSeriesGranularitySchema,
14819
- points: z50.array(trafficSeriesPointSchema)
14834
+ points: z50.array(trafficSeriesPointSchema),
14835
+ /**
14836
+ * Earliest event ever observed for this project, across ALL of its traffic
14837
+ * sources, or null when nothing has been recorded. Buckets before it were
14838
+ * not measured. Earliest-across-sources is deliberate: the band answers
14839
+ * "before this we have nothing", and if any source has data we do not have
14840
+ * nothing. The cost is that a source connected much later hides its own
14841
+ * early gap, which is the better error than marking real data unmeasured.
14842
+ */
14843
+ coverageStart: z50.string().nullable(),
14844
+ /**
14845
+ * Least-squares fit per charted metric, over the densified points.
14846
+ *
14847
+ * Fitted HERE rather than in a chart component: a regression computed in the
14848
+ * UI is invisible to the CLI and to any other consumer, which is the
14849
+ * UI/CLI parity rule. `null` for a metric with fewer than two observations,
14850
+ * so a caller renders "no trend" instead of a fabricated flat line.
14851
+ */
14852
+ trends: z50.object({
14853
+ crawlerContentHits: linearTrendSchema.nullable(),
14854
+ aiUserFetchHits: linearTrendSchema.nullable(),
14855
+ aiReferralLandedHits: linearTrendSchema.nullable()
14856
+ })
14820
14857
  }),
14821
14858
  totals: z50.object({
14822
14859
  /** Total classified-crawler hits across the window. UNCHANGED contract. */
@@ -16921,6 +16958,7 @@ export {
16921
16958
  trafficSeriesGranularitySchema,
16922
16959
  TrafficSeriesGranularities,
16923
16960
  trafficEventsResponseSchema,
16961
+ TrafficPathClasses,
16924
16962
  classifyTrafficPath,
16925
16963
  segmentCrawlerHits,
16926
16964
  sumInfraHits,
@@ -92,7 +92,7 @@ import {
92
92
  trafficConnectWordpressRequestSchema,
93
93
  trafficEventKindSchema,
94
94
  trafficSeriesGranularitySchema
95
- } from "./chunk-IMEJQQZU.js";
95
+ } from "./chunk-A2AB7UK5.js";
96
96
 
97
97
  // src/config.ts
98
98
  import fs from "fs";
@@ -10388,7 +10388,7 @@ var canonryMcpTools = [
10388
10388
  defineTool({
10389
10389
  name: "canonry_apply_config",
10390
10390
  title: "Apply project config",
10391
- description: "Apply one Canonry config-as-code project document. Replaces the project to match the config \u2014 fields omitted from the spec are reset to defaults. For multi-document YAML, call this tool once per project document.",
10391
+ description: "Apply one Canonry config-as-code project document. Replaces the project to match the config \u2014 fields omitted from the spec are reset to defaults, with one exception: a spec with neither queries nor keywords leaves the tracked-query basket unchanged. To clear the basket, pass an explicit empty queries list. For multi-document YAML, call this tool once per project document.",
10392
10392
  access: "write",
10393
10393
  tier: "core",
10394
10394
  inputSchema: applyConfigInputSchema,
@@ -5,11 +5,11 @@ import {
5
5
  installSkills,
6
6
  loadConfigRaw,
7
7
  saveConfigPatch
8
- } from "./chunk-HNY2FNJH.js";
8
+ } from "./chunk-FFXYNYPZ.js";
9
9
  import {
10
10
  SKILL_MANIFEST_FILENAME,
11
11
  SkillsClients
12
- } from "./chunk-IMEJQQZU.js";
12
+ } from "./chunk-A2AB7UK5.js";
13
13
 
14
14
  // src/skills-autosync.ts
15
15
  import fs from "fs";
@@ -11,7 +11,7 @@ import {
11
11
  loadConfig,
12
12
  loadConfigRaw,
13
13
  saveConfigPatch
14
- } from "./chunk-HNY2FNJH.js";
14
+ } from "./chunk-FFXYNYPZ.js";
15
15
  import {
16
16
  CC_CACHE_DIR,
17
17
  DUCKDB_SPEC,
@@ -157,7 +157,7 @@ import {
157
157
  siteCrawlSnapshots,
158
158
  toAlertView,
159
159
  usageCounters
160
- } from "./chunk-KMK6AOB5.js";
160
+ } from "./chunk-5BZWU35I.js";
161
161
  import {
162
162
  AGENT_MEMORY_VALUE_MAX_BYTES,
163
163
  AGENT_PROVIDER_IDS,
@@ -295,7 +295,7 @@ import {
295
295
  validationError,
296
296
  winnabilityClassLabel,
297
297
  withRetry
298
- } from "./chunk-IMEJQQZU.js";
298
+ } from "./chunk-A2AB7UK5.js";
299
299
 
300
300
  // src/telemetry.ts
301
301
  import crypto from "crypto";
@@ -11857,7 +11857,7 @@ function readStoredGroundingSources(rawResponse) {
11857
11857
  return result;
11858
11858
  }
11859
11859
  async function backfillInsightsCommand(project, opts) {
11860
- const { IntelligenceService: IntelligenceService2 } = await import("./intelligence-service-XPAKDZJI.js");
11860
+ const { IntelligenceService: IntelligenceService2 } = await import("./intelligence-service-CKGM2RUJ.js");
11861
11861
  const config = loadConfig();
11862
11862
  const db = createClient(config.database);
11863
11863
  migrate(db);