@ainyc/canonry 4.183.0 → 4.184.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/assets/assets/{AuditHistoryPanel-ClwYugEs.js → AuditHistoryPanel-BoQzQLdL.js} +1 -1
- package/assets/assets/{BacklinksPage-DaEn1w9_.js → BacklinksPage-BMtZIpQj.js} +1 -1
- package/assets/assets/{HistoryPage-B4WWIXmx.js → HistoryPage-CC4O1rGM.js} +1 -1
- package/assets/assets/MeasurementPropertyPage-C08ujTv1.js +1 -0
- package/assets/assets/ProjectPage-BUddJlIf.js +9 -0
- package/assets/assets/{RunRow-0HuBq5KN.js → RunRow-CKp9zNzz.js} +1 -1
- package/assets/assets/RunsPage-w-jscgI3.js +1 -0
- package/assets/assets/{SettingsPage-XzHCmYz4.js → SettingsPage-CtfgpUHc.js} +1 -1
- package/assets/assets/{SiteHealthSection-BODUx0bX.js → SiteHealthSection-C3M1bR9o.js} +3 -3
- package/assets/assets/{TrafficPage-2AKICLH_.js → TrafficPage-Bl0vIyDA.js} +1 -1
- package/assets/assets/{TrafficSourceDetailPage-CYVG7qZ0.js → TrafficSourceDetailPage-B7jgTW9v.js} +1 -1
- package/assets/assets/{extract-error-message-CtGLEBMO.js → extract-error-message-BViVqAMF.js} +1 -1
- package/assets/assets/{index-DwdK2e4e.css → index-D5UC9w71.css} +1 -1
- package/assets/assets/index-aLn_-ngN.js +86 -0
- package/assets/assets/{react-sigma_core.esm.min-D5Honb13.js → react-sigma_core.esm.min-COiFFO4S.js} +1 -1
- package/assets/index.html +2 -2
- package/dist/{chunk-RQSSKN5F.js → chunk-3BF373KE.js} +2 -2
- package/dist/{chunk-ISONU3FA.js → chunk-7ATZMDG2.js} +154 -39
- package/dist/{chunk-OF3PKBW4.js → chunk-AKWR2NKJ.js} +45 -4
- package/dist/{chunk-Z2HTLTQV.js → chunk-DU5Q5ZOX.js} +4571 -4386
- package/dist/{chunk-VFQPW2VX.js → chunk-ROSGBFKI.js} +543 -390
- package/dist/cli.js +13 -157
- package/dist/index.d.ts +2 -0
- package/dist/index.js +4 -4
- package/dist/{intelligence-service-4XQBUFBU.js → intelligence-service-BQIIWWQJ.js} +2 -2
- package/dist/mcp.js +3 -3
- package/package.json +9 -9
- package/assets/assets/MeasurementPropertyPage-DFvelKfS.js +0 -1
- package/assets/assets/ProjectPage-D3AuGcau.js +0 -9
- package/assets/assets/RunsPage-DhdjoIdK.js +0 -1
- package/assets/assets/index-B64WXjg8.js +0 -86
package/assets/assets/{react-sigma_core.esm.min-D5Honb13.js → react-sigma_core.esm.min-COiFFO4S.js}
RENAMED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{g as Bt,t as S,r as C}from"./vendor-tanstack-CYBjbqVr.js";import{e as Ht,G as Wt}from"./SiteHealthSection-
|
|
1
|
+
import{g as Bt,t as S,r as C}from"./vendor-tanstack-CYBjbqVr.js";import{e as Ht,G as Wt}from"./SiteHealthSection-C3M1bR9o.js";import"./index-aLn_-ngN.js";import"./vendor-radix-BpmvLvpp.js";import"./vendor-recharts-FA0uySU7.js";import"./vendor-lucide-XjCNFK0x.js";import"./vendor-markdown-9tTeP8v7.js";import"./vendor-yaml-GWJz5H2G.js";import"./ChartPrimitives-DLEICrrL.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-
|
|
15
|
+
<script type="module" crossorigin src="./assets/index-aLn_-ngN.js"></script>
|
|
16
16
|
<link rel="modulepreload" crossorigin href="./assets/vendor-tanstack-CYBjbqVr.js">
|
|
17
17
|
<link rel="modulepreload" crossorigin href="./assets/vendor-radix-BpmvLvpp.js">
|
|
18
18
|
<link rel="modulepreload" crossorigin href="./assets/vendor-recharts-FA0uySU7.js">
|
|
19
19
|
<link rel="modulepreload" crossorigin href="./assets/vendor-lucide-XjCNFK0x.js">
|
|
20
20
|
<link rel="modulepreload" crossorigin href="./assets/vendor-markdown-9tTeP8v7.js">
|
|
21
21
|
<link rel="modulepreload" crossorigin href="./assets/vendor-yaml-GWJz5H2G.js">
|
|
22
|
-
<link rel="stylesheet" crossorigin href="./assets/index-
|
|
22
|
+
<link rel="stylesheet" crossorigin href="./assets/index-D5UC9w71.css">
|
|
23
23
|
</head>
|
|
24
24
|
<body>
|
|
25
25
|
<div id="root"></div>
|
|
@@ -5,11 +5,11 @@ import {
|
|
|
5
5
|
installSkills,
|
|
6
6
|
loadConfigRaw,
|
|
7
7
|
saveConfigPatch
|
|
8
|
-
} from "./chunk-
|
|
8
|
+
} from "./chunk-ROSGBFKI.js";
|
|
9
9
|
import {
|
|
10
10
|
SKILL_MANIFEST_FILENAME,
|
|
11
11
|
SkillsClients
|
|
12
|
-
} from "./chunk-
|
|
12
|
+
} from "./chunk-DU5Q5ZOX.js";
|
|
13
13
|
|
|
14
14
|
// src/skills-autosync.ts
|
|
15
15
|
import fs from "fs";
|
|
@@ -209,6 +209,7 @@ import {
|
|
|
209
209
|
canonicalMeasurementPlanJson,
|
|
210
210
|
canonicalMeasurementPlanV2,
|
|
211
211
|
canonicalMeasurementPlanV2Json,
|
|
212
|
+
canonicalSimpleMeasurementDefinitionJson,
|
|
212
213
|
canonicalizeAdsActivationManifest,
|
|
213
214
|
canonicalizeGoogleAdsCustomerSelection,
|
|
214
215
|
canonicalizeGtmAccountId,
|
|
@@ -573,6 +574,7 @@ import {
|
|
|
573
574
|
serializeRunError,
|
|
574
575
|
settingsDtoSchema,
|
|
575
576
|
shiftIsoCalendarDate,
|
|
577
|
+
simpleMeasurementDefinitionSchema,
|
|
576
578
|
siteAuditLivePageHealthSchema,
|
|
577
579
|
siteAuditPageFactorSchema,
|
|
578
580
|
siteAuditPagesResponseSchema,
|
|
@@ -652,10 +654,10 @@ import {
|
|
|
652
654
|
wordpressSchemaDeployResultDtoSchema,
|
|
653
655
|
wordpressSchemaStatusResultDtoSchema,
|
|
654
656
|
wordpressStatusDtoSchema
|
|
655
|
-
} from "./chunk-
|
|
657
|
+
} from "./chunk-DU5Q5ZOX.js";
|
|
656
658
|
|
|
657
659
|
// src/intelligence-service.ts
|
|
658
|
-
import { eq as
|
|
660
|
+
import { eq as eq64, desc as desc27, asc as asc12, and as and53, ne as ne8, or as or14, inArray as inArray23, gte as gte16, lte as lte13, isNull as isNull9, sql as sql25, exists } from "drizzle-orm";
|
|
659
661
|
|
|
660
662
|
// ../db/src/client.ts
|
|
661
663
|
import { mkdirSync } from "fs";
|
|
@@ -756,6 +758,7 @@ __export(schema_exports, {
|
|
|
756
758
|
researchRuns: () => researchRuns,
|
|
757
759
|
runs: () => runs,
|
|
758
760
|
schedules: () => schedules,
|
|
761
|
+
simpleMeasurementDefinitions: () => simpleMeasurementDefinitions,
|
|
759
762
|
siteAuditPages: () => siteAuditPages,
|
|
760
763
|
siteAuditSnapshots: () => siteAuditSnapshots,
|
|
761
764
|
siteCrawlAttempts: () => siteCrawlAttempts,
|
|
@@ -1016,6 +1019,20 @@ var runs = sqliteTable("runs", {
|
|
|
1016
1019
|
foreignColumns: [measurementPlanVersions.projectId, measurementPlanVersions.id]
|
|
1017
1020
|
})
|
|
1018
1021
|
]);
|
|
1022
|
+
var simpleMeasurementDefinitions = sqliteTable("simple_measurement_definitions", {
|
|
1023
|
+
runId: text("run_id").notNull().primaryKey(),
|
|
1024
|
+
projectId: text("project_id").notNull(),
|
|
1025
|
+
definition: text("definition", { mode: "json" }).$type().notNull(),
|
|
1026
|
+
checksum: text("checksum").notNull(),
|
|
1027
|
+
capturedAt: text("captured_at").notNull()
|
|
1028
|
+
}, (table) => [
|
|
1029
|
+
index("idx_simple_measurement_definitions_project").on(table.projectId),
|
|
1030
|
+
foreignKey({
|
|
1031
|
+
name: "simple_measurement_definitions_project_run_fk",
|
|
1032
|
+
columns: [table.projectId, table.runId],
|
|
1033
|
+
foreignColumns: [runs.projectId, runs.id]
|
|
1034
|
+
}).onDelete("cascade")
|
|
1035
|
+
]);
|
|
1019
1036
|
var queryBasketVersions = sqliteTable("query_basket_versions", {
|
|
1020
1037
|
projectId: text("project_id").notNull().references(() => projects.id, { onDelete: "cascade" }),
|
|
1021
1038
|
revision: integer("revision").notNull(),
|
|
@@ -7080,6 +7097,36 @@ var MIGRATION_VERSIONS = [
|
|
|
7080
7097
|
statements: [
|
|
7081
7098
|
`ALTER TABLE measurement_plan_versions ADD COLUMN comparable_to_version_id TEXT`
|
|
7082
7099
|
]
|
|
7100
|
+
},
|
|
7101
|
+
{
|
|
7102
|
+
// A simple (planless) run resolves its live inputs at dispatch, not queue
|
|
7103
|
+
// time. The sidecar freezes only new captures; historic runs intentionally
|
|
7104
|
+
// remain absent because no truthful definition can be reconstructed for
|
|
7105
|
+
// them. It is deliberately separate from the advanced-plan manifest and
|
|
7106
|
+
// checksum/continuity chain.
|
|
7107
|
+
version: 150,
|
|
7108
|
+
name: "simple-measurement-definitions",
|
|
7109
|
+
statements: [
|
|
7110
|
+
`CREATE TABLE IF NOT EXISTS simple_measurement_definitions (
|
|
7111
|
+
run_id TEXT PRIMARY KEY NOT NULL,
|
|
7112
|
+
project_id TEXT NOT NULL,
|
|
7113
|
+
definition TEXT NOT NULL,
|
|
7114
|
+
checksum TEXT NOT NULL,
|
|
7115
|
+
captured_at TEXT NOT NULL,
|
|
7116
|
+
FOREIGN KEY (project_id, run_id)
|
|
7117
|
+
REFERENCES runs(project_id, id) ON DELETE CASCADE
|
|
7118
|
+
)`,
|
|
7119
|
+
`CREATE INDEX IF NOT EXISTS idx_simple_measurement_definitions_project
|
|
7120
|
+
ON simple_measurement_definitions(project_id)`,
|
|
7121
|
+
// Frozen input cannot be corrected in place: a retry must either reuse
|
|
7122
|
+
// this exact definition or start a distinct run, never reinterpret a
|
|
7123
|
+
// stored answer through newly-current project settings.
|
|
7124
|
+
`CREATE TRIGGER IF NOT EXISTS simple_measurement_definitions_no_update
|
|
7125
|
+
BEFORE UPDATE ON simple_measurement_definitions
|
|
7126
|
+
BEGIN
|
|
7127
|
+
SELECT RAISE(ABORT, 'simple measurement definition is immutable');
|
|
7128
|
+
END`
|
|
7129
|
+
]
|
|
7083
7130
|
}
|
|
7084
7131
|
];
|
|
7085
7132
|
function addRunsMeasurementPlanVersionForeignKey(tx) {
|
|
@@ -79680,6 +79727,73 @@ function serializeQuery(row) {
|
|
|
79680
79727
|
return { id: row.id, position: row.position, query: row.queryText, status: row.status, requestedModel: row.requestedModel, resolvedModel: row.resolvedModel, servedModel: row.servedModel, answerText: row.answerText, groundingSources: row.groundingSources, citedDomains: row.citedDomains, searchQueries: row.searchQueries, namedCompetitors: row.namedCompetitors, citedCompetitorDomains: row.citedCompetitorDomains, answerMentioned: row.answerMentioned, citationState: row.citationState, error: row.error, startedAt: row.startedAt, finishedAt: row.finishedAt, createdAt: row.createdAt };
|
|
79681
79728
|
}
|
|
79682
79729
|
|
|
79730
|
+
// ../api-routes/src/simple-measurement-definitions.ts
|
|
79731
|
+
import crypto49 from "crypto";
|
|
79732
|
+
import { and as and52, eq as eq63 } from "drizzle-orm";
|
|
79733
|
+
function captureSimpleMeasurementDefinition(db, input) {
|
|
79734
|
+
return db.transaction((tx) => {
|
|
79735
|
+
const run = tx.select({
|
|
79736
|
+
kind: runs.kind,
|
|
79737
|
+
trigger: runs.trigger,
|
|
79738
|
+
status: runs.status,
|
|
79739
|
+
measurementPlanVersionId: runs.measurementPlanVersionId
|
|
79740
|
+
}).from(runs).where(and52(eq63(runs.projectId, input.projectId), eq63(runs.id, input.runId))).get();
|
|
79741
|
+
if (!run) throw notFound("Run", input.runId);
|
|
79742
|
+
if (run.kind !== RunKinds["answer-visibility"] || run.trigger === RunTriggers.probe || run.measurementPlanVersionId !== null) {
|
|
79743
|
+
return null;
|
|
79744
|
+
}
|
|
79745
|
+
const definition = simpleMeasurementDefinitionSchema.parse(input.definition);
|
|
79746
|
+
const classifier = compileQueryClassifier(effectiveBrandNames(definition.identity));
|
|
79747
|
+
if (definition.queries.some((query) => query.queryClass !== (classifier?.classify(query.queryText) ?? null))) {
|
|
79748
|
+
throw validationError("Query classes must match the captured identity and text.");
|
|
79749
|
+
}
|
|
79750
|
+
const existing = tx.select().from(simpleMeasurementDefinitions).where(and52(eq63(simpleMeasurementDefinitions.projectId, input.projectId), eq63(simpleMeasurementDefinitions.runId, input.runId))).get();
|
|
79751
|
+
if (existing) {
|
|
79752
|
+
const frozen = simpleMeasurementDefinitionSchema.parse(existing.definition);
|
|
79753
|
+
const replayDefinition = {
|
|
79754
|
+
...definition,
|
|
79755
|
+
capturedAt: frozen.capturedAt
|
|
79756
|
+
};
|
|
79757
|
+
const replayChecksum = crypto49.createHash("sha256").update(canonicalSimpleMeasurementDefinitionJson(replayDefinition)).digest("hex");
|
|
79758
|
+
if (existing.checksum !== replayChecksum) {
|
|
79759
|
+
if (frozen.competitors === void 0) {
|
|
79760
|
+
const { competitors: _currentCompetitors, ...legacyReplayDefinition } = replayDefinition;
|
|
79761
|
+
const legacyReplayChecksum = crypto49.createHash("sha256").update(canonicalSimpleMeasurementDefinitionJson(legacyReplayDefinition)).digest("hex");
|
|
79762
|
+
if (existing.checksum === legacyReplayChecksum) return frozen;
|
|
79763
|
+
}
|
|
79764
|
+
throw validationError("This run already has a captured measurement definition. Start a new run for changed inputs.");
|
|
79765
|
+
}
|
|
79766
|
+
return frozen;
|
|
79767
|
+
}
|
|
79768
|
+
if (run.status !== RunStatuses.running) {
|
|
79769
|
+
throw validationError("Only a running run can capture a new measurement definition.");
|
|
79770
|
+
}
|
|
79771
|
+
if (tx.select({ id: querySnapshots.id }).from(querySnapshots).where(eq63(querySnapshots.runId, input.runId)).limit(1).get()) {
|
|
79772
|
+
throw validationError("This run already has stored answers. Its measurement definition cannot be inferred afterward.");
|
|
79773
|
+
}
|
|
79774
|
+
const projectQueryIds = new Set(tx.select({ id: queries.id }).from(queries).where(eq63(queries.projectId, input.projectId)).all().map((query) => query.id));
|
|
79775
|
+
if (definition.queries.some((query) => !projectQueryIds.has(query.queryId))) {
|
|
79776
|
+
throw validationError("Every captured query must belong to the run project.");
|
|
79777
|
+
}
|
|
79778
|
+
if (definition.competitors !== void 0) {
|
|
79779
|
+
const liveCompetitorDomains = new Set(tx.select({ domain: competitors.domain }).from(competitors).where(eq63(competitors.projectId, input.projectId)).all().map((competitor) => competitor.domain));
|
|
79780
|
+
const capturedDomains = new Set(definition.competitors.map((competitor) => competitor.domain));
|
|
79781
|
+
if (liveCompetitorDomains.size !== capturedDomains.size || [...liveCompetitorDomains].some((domain) => !capturedDomains.has(domain))) {
|
|
79782
|
+
throw validationError("Captured competitors must exactly match the project competitors dispatched for this run.");
|
|
79783
|
+
}
|
|
79784
|
+
}
|
|
79785
|
+
const checksum = crypto49.createHash("sha256").update(canonicalSimpleMeasurementDefinitionJson(definition)).digest("hex");
|
|
79786
|
+
tx.insert(simpleMeasurementDefinitions).values({
|
|
79787
|
+
projectId: input.projectId,
|
|
79788
|
+
runId: input.runId,
|
|
79789
|
+
definition,
|
|
79790
|
+
checksum,
|
|
79791
|
+
capturedAt: definition.capturedAt
|
|
79792
|
+
}).run();
|
|
79793
|
+
return definition;
|
|
79794
|
+
});
|
|
79795
|
+
}
|
|
79796
|
+
|
|
79683
79797
|
// ../api-routes/src/index.ts
|
|
79684
79798
|
async function apiRoutes(app, opts) {
|
|
79685
79799
|
app.decorate("db", opts.db);
|
|
@@ -80185,7 +80299,7 @@ function buildTrafficSourceValidators(opts) {
|
|
|
80185
80299
|
}
|
|
80186
80300
|
|
|
80187
80301
|
// src/intelligence-service.ts
|
|
80188
|
-
import
|
|
80302
|
+
import crypto50 from "crypto";
|
|
80189
80303
|
|
|
80190
80304
|
// src/logger.ts
|
|
80191
80305
|
var IS_TTY = process.stdout.isTTY === true;
|
|
@@ -80373,10 +80487,10 @@ var log = createLogger("IntelligenceService");
|
|
|
80373
80487
|
var runChronologyKey = sql25`coalesce(${runs.finishedAt}, ${runs.createdAt})`;
|
|
80374
80488
|
function analyzableRunPredicates(projectId) {
|
|
80375
80489
|
return [
|
|
80376
|
-
|
|
80490
|
+
eq64(runs.projectId, projectId),
|
|
80377
80491
|
// Only this kind writes query_snapshots.
|
|
80378
|
-
|
|
80379
|
-
or14(
|
|
80492
|
+
eq64(runs.kind, RunKinds["answer-visibility"]),
|
|
80493
|
+
or14(eq64(runs.status, RunStatuses.completed), eq64(runs.status, RunStatuses.partial)),
|
|
80380
80494
|
// Defensive: RunCoordinator already skips probes before analyzeAndPersist
|
|
80381
80495
|
// is called, but a future call site invoking it directly for a probe must
|
|
80382
80496
|
// still not pollute the intelligence window.
|
|
@@ -80421,16 +80535,16 @@ var IntelligenceService = class {
|
|
|
80421
80535
|
* Returns the analysis result for the coordinator to inspect (e.g. for webhook dispatch).
|
|
80422
80536
|
*/
|
|
80423
80537
|
analyzeAndPersist(runId, projectId) {
|
|
80424
|
-
const currentRunRecord = this.db.select().from(runs).where(
|
|
80538
|
+
const currentRunRecord = this.db.select().from(runs).where(and53(eq64(runs.id, runId), ...analyzableRunPredicates(projectId))).get();
|
|
80425
80539
|
if (!currentRunRecord) {
|
|
80426
80540
|
log.info("intelligence.skip", { runId, reason: "run not eligible for analysis" });
|
|
80427
80541
|
return null;
|
|
80428
80542
|
}
|
|
80429
80543
|
const currentLocation = currentRunRecord.location ?? null;
|
|
80430
80544
|
const recentRuns = this.db.select().from(runs).where(
|
|
80431
|
-
|
|
80545
|
+
and53(
|
|
80432
80546
|
...analyzableRunPredicates(projectId),
|
|
80433
|
-
currentLocation === null ? isNull9(runs.location) :
|
|
80547
|
+
currentLocation === null ? isNull9(runs.location) : eq64(runs.location, currentLocation),
|
|
80434
80548
|
// Never look forward. The window is this run's own past, so
|
|
80435
80549
|
// re-analyzing a historical run compares it against its true
|
|
80436
80550
|
// predecessor rather than against sweeps that came after it.
|
|
@@ -80438,7 +80552,7 @@ var IntelligenceService = class {
|
|
|
80438
80552
|
// MEASUREMENT: only runs that actually wrote snapshots — see above.
|
|
80439
80553
|
// Index seek on idx_snapshots_run, short-circuited on the first row.
|
|
80440
80554
|
exists(
|
|
80441
|
-
this.db.select({ one: sql25`1` }).from(querySnapshots).where(
|
|
80555
|
+
this.db.select({ one: sql25`1` }).from(querySnapshots).where(eq64(querySnapshots.runId, runs.id))
|
|
80442
80556
|
)
|
|
80443
80557
|
)
|
|
80444
80558
|
).orderBy(desc27(runs.finishedAt), desc27(runs.createdAt)).limit(HISTORY_WINDOW_RUNS).all();
|
|
@@ -80513,7 +80627,7 @@ var IntelligenceService = class {
|
|
|
80513
80627
|
* Returns the persisted insights so the coordinator can count critical/high.
|
|
80514
80628
|
*/
|
|
80515
80629
|
analyzeAndPersistGbp(runId, projectId) {
|
|
80516
|
-
const runRow = this.db.select({ createdAt: runs.createdAt, startedAt: runs.startedAt, finishedAt: runs.finishedAt }).from(runs).where(
|
|
80630
|
+
const runRow = this.db.select({ createdAt: runs.createdAt, startedAt: runs.startedAt, finishedAt: runs.finishedAt }).from(runs).where(eq64(runs.id, runId)).get();
|
|
80517
80631
|
if (!runRow) {
|
|
80518
80632
|
log.info("gbp-intelligence.skip", { runId, reason: "run not found" });
|
|
80519
80633
|
this.persistGbpInsights(runId, projectId, [], []);
|
|
@@ -80521,9 +80635,9 @@ var IntelligenceService = class {
|
|
|
80521
80635
|
}
|
|
80522
80636
|
const windowStart = runRow.startedAt ?? runRow.createdAt;
|
|
80523
80637
|
const windowEnd = runRow.finishedAt ?? (/* @__PURE__ */ new Date()).toISOString();
|
|
80524
|
-
const selected = this.db.select().from(gbpLocations).where(
|
|
80525
|
-
|
|
80526
|
-
|
|
80638
|
+
const selected = this.db.select().from(gbpLocations).where(and53(
|
|
80639
|
+
eq64(gbpLocations.projectId, projectId),
|
|
80640
|
+
eq64(gbpLocations.selected, true),
|
|
80527
80641
|
gte16(gbpLocations.syncedAt, windowStart),
|
|
80528
80642
|
lte13(gbpLocations.syncedAt, windowEnd)
|
|
80529
80643
|
)).all();
|
|
@@ -80558,12 +80672,12 @@ var IntelligenceService = class {
|
|
|
80558
80672
|
}
|
|
80559
80673
|
/** Build the per-location signal bundle the GBP analyzer consumes. */
|
|
80560
80674
|
buildGbpLocationSignals(projectId, locationName, displayName, fallbackDate) {
|
|
80561
|
-
const metricRows = this.db.select({ metric: gbpDailyMetrics.metric, date: gbpDailyMetrics.date, value: gbpDailyMetrics.value }).from(gbpDailyMetrics).where(
|
|
80562
|
-
const placeActionRows = this.db.select({ placeActionType: gbpPlaceActions.placeActionType, providerType: gbpPlaceActions.providerType }).from(gbpPlaceActions).where(
|
|
80563
|
-
const lodgingRow = this.db.select({ populatedGroupCount: gbpLodgingSnapshots.populatedGroupCount }).from(gbpLodgingSnapshots).where(
|
|
80564
|
-
const ownerRow = this.db.select({ description: gbpLocations.description }).from(gbpLocations).where(
|
|
80675
|
+
const metricRows = this.db.select({ metric: gbpDailyMetrics.metric, date: gbpDailyMetrics.date, value: gbpDailyMetrics.value }).from(gbpDailyMetrics).where(and53(eq64(gbpDailyMetrics.projectId, projectId), eq64(gbpDailyMetrics.locationName, locationName))).all();
|
|
80676
|
+
const placeActionRows = this.db.select({ placeActionType: gbpPlaceActions.placeActionType, providerType: gbpPlaceActions.providerType }).from(gbpPlaceActions).where(and53(eq64(gbpPlaceActions.projectId, projectId), eq64(gbpPlaceActions.locationName, locationName))).all();
|
|
80677
|
+
const lodgingRow = this.db.select({ populatedGroupCount: gbpLodgingSnapshots.populatedGroupCount }).from(gbpLodgingSnapshots).where(and53(eq64(gbpLodgingSnapshots.projectId, projectId), eq64(gbpLodgingSnapshots.locationName, locationName))).orderBy(desc27(gbpLodgingSnapshots.syncedAt)).limit(1).get();
|
|
80678
|
+
const ownerRow = this.db.select({ description: gbpLocations.description }).from(gbpLocations).where(and53(eq64(gbpLocations.projectId, projectId), eq64(gbpLocations.locationName, locationName))).get();
|
|
80565
80679
|
const descriptionMissing = !(ownerRow?.description ?? "").trim();
|
|
80566
|
-
const placeRow = this.db.select({ attributes: gbpPlaceDetails.attributes }).from(gbpPlaceDetails).where(
|
|
80680
|
+
const placeRow = this.db.select({ attributes: gbpPlaceDetails.attributes }).from(gbpPlaceDetails).where(and53(eq64(gbpPlaceDetails.projectId, projectId), eq64(gbpPlaceDetails.locationName, locationName))).orderBy(desc27(gbpPlaceDetails.syncedAt)).limit(1).get();
|
|
80567
80681
|
const placesAmenities = placeRow ? extractPlaceAmenities(placeRow.attributes) : [];
|
|
80568
80682
|
const summary = buildGbpSummary({
|
|
80569
80683
|
locationName,
|
|
@@ -80599,7 +80713,7 @@ var IntelligenceService = class {
|
|
|
80599
80713
|
/** Build the month-over-month keyword series for a location from the
|
|
80600
80714
|
* accumulating gbp_keyword_monthly table (latest complete month vs prior). */
|
|
80601
80715
|
buildGbpKeywordTrend(projectId, locationName) {
|
|
80602
|
-
const rows = this.db.select({ month: gbpKeywordMonthly.month, keyword: gbpKeywordMonthly.keyword, valueCount: gbpKeywordMonthly.valueCount }).from(gbpKeywordMonthly).where(
|
|
80716
|
+
const rows = this.db.select({ month: gbpKeywordMonthly.month, keyword: gbpKeywordMonthly.keyword, valueCount: gbpKeywordMonthly.valueCount }).from(gbpKeywordMonthly).where(and53(eq64(gbpKeywordMonthly.projectId, projectId), eq64(gbpKeywordMonthly.locationName, locationName))).all();
|
|
80603
80717
|
if (rows.length === 0) return { recentMonth: null, priorMonth: null, points: [] };
|
|
80604
80718
|
const months = [...new Set(rows.map((r) => r.month))].sort().reverse();
|
|
80605
80719
|
const recentMonth = months[0] ?? null;
|
|
@@ -80630,7 +80744,7 @@ var IntelligenceService = class {
|
|
|
80630
80744
|
*/
|
|
80631
80745
|
persistGbpInsights(runId, projectId, gbpInsights, coveredLocationNames) {
|
|
80632
80746
|
const covered = new Set(coveredLocationNames);
|
|
80633
|
-
const existing = this.db.select({ id: insights.id, dismissed: insights.dismissed }).from(insights).where(
|
|
80747
|
+
const existing = this.db.select({ id: insights.id, dismissed: insights.dismissed }).from(insights).where(and53(eq64(insights.projectId, projectId), eq64(insights.provider, GBP_INSIGHT_PROVIDER))).all();
|
|
80634
80748
|
const staleIds = [];
|
|
80635
80749
|
const dismissedSlots = /* @__PURE__ */ new Set();
|
|
80636
80750
|
for (const row of existing) {
|
|
@@ -80641,7 +80755,7 @@ var IntelligenceService = class {
|
|
|
80641
80755
|
}
|
|
80642
80756
|
this.db.transaction((tx) => {
|
|
80643
80757
|
for (const id of staleIds) {
|
|
80644
|
-
tx.delete(insights).where(
|
|
80758
|
+
tx.delete(insights).where(eq64(insights.id, id)).run();
|
|
80645
80759
|
}
|
|
80646
80760
|
for (const insight of gbpInsights) {
|
|
80647
80761
|
const parsed = parseGbpInsightId(insight.id);
|
|
@@ -80727,7 +80841,7 @@ var IntelligenceService = class {
|
|
|
80727
80841
|
* create per run + aggregate). DB is left untouched.
|
|
80728
80842
|
*/
|
|
80729
80843
|
backfill(projectName, opts, onProgress) {
|
|
80730
|
-
const project = this.db.select().from(projects).where(
|
|
80844
|
+
const project = this.db.select().from(projects).where(eq64(projects.name, projectName)).get();
|
|
80731
80845
|
if (!project) {
|
|
80732
80846
|
throw new Error(`Project "${projectName}" not found`);
|
|
80733
80847
|
}
|
|
@@ -80739,7 +80853,7 @@ var IntelligenceService = class {
|
|
|
80739
80853
|
}
|
|
80740
80854
|
sinceTimestamp = parsed;
|
|
80741
80855
|
}
|
|
80742
|
-
const allRuns = this.db.select().from(runs).where(
|
|
80856
|
+
const allRuns = this.db.select().from(runs).where(and53(...analyzableRunPredicates(project.id))).orderBy(asc12(runs.finishedAt)).all();
|
|
80743
80857
|
const measuredRunIds = this.runIdsWithSnapshots(allRuns.map((r) => r.id));
|
|
80744
80858
|
const measuredRuns = allRuns.filter((r) => measuredRunIds.has(r.id));
|
|
80745
80859
|
let startIdx = 0;
|
|
@@ -80816,7 +80930,7 @@ var IntelligenceService = class {
|
|
|
80816
80930
|
return { processed, skipped, totalInsights };
|
|
80817
80931
|
}
|
|
80818
80932
|
loadTrackedCompetitors(projectId) {
|
|
80819
|
-
return this.db.select({ domain: competitors.domain }).from(competitors).where(
|
|
80933
|
+
return this.db.select({ domain: competitors.domain }).from(competitors).where(eq64(competitors.projectId, projectId)).all().map((r) => r.domain);
|
|
80820
80934
|
}
|
|
80821
80935
|
/**
|
|
80822
80936
|
* Which of `runIds` actually wrote query snapshots. One grouped read, so
|
|
@@ -80847,15 +80961,15 @@ var IntelligenceService = class {
|
|
|
80847
80961
|
}
|
|
80848
80962
|
persistResult(result, runId, projectId) {
|
|
80849
80963
|
const previouslyDismissed = /* @__PURE__ */ new Set();
|
|
80850
|
-
const existingInsights = this.db.select({ query: insights.query, provider: insights.provider, type: insights.type, dismissed: insights.dismissed }).from(insights).where(
|
|
80964
|
+
const existingInsights = this.db.select({ query: insights.query, provider: insights.provider, type: insights.type, dismissed: insights.dismissed }).from(insights).where(eq64(insights.runId, runId)).all();
|
|
80851
80965
|
for (const row of existingInsights) {
|
|
80852
80966
|
if (row.dismissed) {
|
|
80853
80967
|
previouslyDismissed.add(`${row.query}:${row.provider}:${row.type}`);
|
|
80854
80968
|
}
|
|
80855
80969
|
}
|
|
80856
80970
|
this.db.transaction((tx) => {
|
|
80857
|
-
tx.delete(insights).where(
|
|
80858
|
-
tx.delete(healthSnapshots).where(
|
|
80971
|
+
tx.delete(insights).where(eq64(insights.runId, runId)).run();
|
|
80972
|
+
tx.delete(healthSnapshots).where(eq64(healthSnapshots.runId, runId)).run();
|
|
80859
80973
|
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
80860
80974
|
for (const insight of result.insights) {
|
|
80861
80975
|
const wasDismissed = previouslyDismissed.has(`${insight.query}:${insight.provider}:${insight.type}`);
|
|
@@ -80875,7 +80989,7 @@ var IntelligenceService = class {
|
|
|
80875
80989
|
}).run();
|
|
80876
80990
|
}
|
|
80877
80991
|
tx.insert(healthSnapshots).values({
|
|
80878
|
-
id:
|
|
80992
|
+
id: crypto50.randomUUID(),
|
|
80879
80993
|
projectId,
|
|
80880
80994
|
runId,
|
|
80881
80995
|
overallCitedRate: String(result.health.overallCitedRate),
|
|
@@ -80902,8 +81016,8 @@ var IntelligenceService = class {
|
|
|
80902
81016
|
clicks: gscSearchData.clicks,
|
|
80903
81017
|
impressions: gscSearchData.impressions,
|
|
80904
81018
|
position: gscSearchData.position
|
|
80905
|
-
}).from(gscSearchData).where(
|
|
80906
|
-
|
|
81019
|
+
}).from(gscSearchData).where(and53(
|
|
81020
|
+
eq64(gscSearchData.projectId, projectId),
|
|
80907
81021
|
gte16(gscSearchData.date, window.startDate),
|
|
80908
81022
|
lte13(gscSearchData.date, window.endDate)
|
|
80909
81023
|
)).all();
|
|
@@ -80956,17 +81070,17 @@ var IntelligenceService = class {
|
|
|
80956
81070
|
const key = row.query.toLowerCase();
|
|
80957
81071
|
gscImpressionsByQuery.set(key, (gscImpressionsByQuery.get(key) ?? 0) + row.impressions);
|
|
80958
81072
|
}
|
|
80959
|
-
const projectRow = this.db.select({ locations: projects.locations }).from(projects).where(
|
|
81073
|
+
const projectRow = this.db.select({ locations: projects.locations }).from(projects).where(eq64(projects.id, projectId)).get();
|
|
80960
81074
|
const locationCount = Math.max(
|
|
80961
81075
|
1,
|
|
80962
81076
|
(projectRow?.locations ?? []).length
|
|
80963
81077
|
);
|
|
80964
81078
|
const ROWS_PER_GROUP_BUDGET = Math.max(2, locationCount);
|
|
80965
81079
|
const recentRunRows = this.db.select({ id: runs.id, createdAt: runs.createdAt }).from(runs).where(
|
|
80966
|
-
|
|
80967
|
-
|
|
80968
|
-
|
|
80969
|
-
or14(
|
|
81080
|
+
and53(
|
|
81081
|
+
eq64(runs.projectId, projectId),
|
|
81082
|
+
eq64(runs.kind, RunKinds["answer-visibility"]),
|
|
81083
|
+
or14(eq64(runs.status, "completed"), eq64(runs.status, "partial")),
|
|
80970
81084
|
// Defensive — see top of file.
|
|
80971
81085
|
ne8(runs.trigger, RunTriggers.probe)
|
|
80972
81086
|
)
|
|
@@ -80986,7 +81100,7 @@ var IntelligenceService = class {
|
|
|
80986
81100
|
const haveHistory = recentRunIds.length > 0;
|
|
80987
81101
|
const priorRegressionsByPair = /* @__PURE__ */ new Map();
|
|
80988
81102
|
if (haveHistory) {
|
|
80989
|
-
const priorRows = this.db.select({ query: insights.query, provider: insights.provider, runId: insights.runId }).from(insights).where(
|
|
81103
|
+
const priorRows = this.db.select({ query: insights.query, provider: insights.provider, runId: insights.runId }).from(insights).where(and53(eq64(insights.type, "regression"), inArray23(insights.runId, recentRunIds))).all();
|
|
80990
81104
|
const regressionGroups = /* @__PURE__ */ new Map();
|
|
80991
81105
|
for (const row of priorRows) {
|
|
80992
81106
|
if (!row.runId) continue;
|
|
@@ -81015,7 +81129,7 @@ var IntelligenceService = class {
|
|
|
81015
81129
|
});
|
|
81016
81130
|
}
|
|
81017
81131
|
buildRunData(runId, projectId, completedAt, location = null, trackedCompetitors = []) {
|
|
81018
|
-
const projectDomainRow = this.db.select({ canonicalDomain: projects.canonicalDomain, ownedDomains: projects.ownedDomains }).from(projects).where(
|
|
81132
|
+
const projectDomainRow = this.db.select({ canonicalDomain: projects.canonicalDomain, ownedDomains: projects.ownedDomains }).from(projects).where(eq64(projects.id, projectId)).get();
|
|
81019
81133
|
const projectDomains = projectDomainRow ? effectiveDomains({
|
|
81020
81134
|
canonicalDomain: projectDomainRow.canonicalDomain,
|
|
81021
81135
|
ownedDomains: projectDomainRow.ownedDomains
|
|
@@ -81033,7 +81147,7 @@ var IntelligenceService = class {
|
|
|
81033
81147
|
citedDomains: querySnapshots.citedDomains,
|
|
81034
81148
|
rawResponse: querySnapshots.rawResponse,
|
|
81035
81149
|
snapshotLocation: querySnapshots.location
|
|
81036
|
-
}).from(querySnapshots).leftJoin(queries,
|
|
81150
|
+
}).from(querySnapshots).leftJoin(queries, eq64(querySnapshots.queryId, queries.id)).where(eq64(querySnapshots.runId, runId)).all();
|
|
81037
81151
|
const snapshots = [];
|
|
81038
81152
|
let orphanCount = 0;
|
|
81039
81153
|
for (const r of rows) {
|
|
@@ -81227,6 +81341,7 @@ export {
|
|
|
81227
81341
|
generateWranglerToml,
|
|
81228
81342
|
executeDiscovery,
|
|
81229
81343
|
markSessionFailed,
|
|
81344
|
+
captureSimpleMeasurementDefinition,
|
|
81230
81345
|
apiRoutes,
|
|
81231
81346
|
createLogger,
|
|
81232
81347
|
IntelligenceService
|
|
@@ -11,7 +11,7 @@ import {
|
|
|
11
11
|
loadConfig,
|
|
12
12
|
loadConfigRaw,
|
|
13
13
|
saveConfigPatch
|
|
14
|
-
} from "./chunk-
|
|
14
|
+
} from "./chunk-ROSGBFKI.js";
|
|
15
15
|
import {
|
|
16
16
|
CC_CACHE_DIR,
|
|
17
17
|
DUCKDB_SPEC,
|
|
@@ -40,6 +40,7 @@ import {
|
|
|
40
40
|
bingCoverageSnapshots,
|
|
41
41
|
bingUrlInspections,
|
|
42
42
|
buildLocationProfileFields,
|
|
43
|
+
captureSimpleMeasurementDefinition,
|
|
43
44
|
ccReleasePaths,
|
|
44
45
|
ccReleaseSyncs,
|
|
45
46
|
classifyAiUserFetch,
|
|
@@ -157,7 +158,7 @@ import {
|
|
|
157
158
|
siteCrawlSnapshots,
|
|
158
159
|
toAlertView,
|
|
159
160
|
usageCounters
|
|
160
|
-
} from "./chunk-
|
|
161
|
+
} from "./chunk-7ATZMDG2.js";
|
|
161
162
|
import {
|
|
162
163
|
AGENT_MEMORY_VALUE_MAX_BYTES,
|
|
163
164
|
AGENT_PROVIDER_IDS,
|
|
@@ -214,8 +215,10 @@ import {
|
|
|
214
215
|
agentMemoryUpsertRequestSchema,
|
|
215
216
|
authInvalid,
|
|
216
217
|
authRequired,
|
|
218
|
+
brandLabelFromDomain,
|
|
217
219
|
bucketOnboardingCount,
|
|
218
220
|
buildRunErrorFromMessages,
|
|
221
|
+
buildSimpleMeasurementDefinition,
|
|
219
222
|
canonicalizeGtmAccountId,
|
|
220
223
|
canonicalizeGtmContainerId,
|
|
221
224
|
canonicalizeGtmResourceSelection,
|
|
@@ -296,7 +299,7 @@ import {
|
|
|
296
299
|
validationError,
|
|
297
300
|
winnabilityClassLabel,
|
|
298
301
|
withRetry
|
|
299
|
-
} from "./chunk-
|
|
302
|
+
} from "./chunk-DU5Q5ZOX.js";
|
|
300
303
|
|
|
301
304
|
// src/telemetry.ts
|
|
302
305
|
import crypto from "crypto";
|
|
@@ -6860,6 +6863,37 @@ var JobRunner = class {
|
|
|
6860
6863
|
}
|
|
6861
6864
|
}
|
|
6862
6865
|
};
|
|
6866
|
+
if (existingRun.kind === RunKinds["answer-visibility"] && existingRun.trigger !== RunTriggers.probe && existingRun.measurementPlanVersionId === null) {
|
|
6867
|
+
const definition = buildSimpleMeasurementDefinition({
|
|
6868
|
+
capturedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
6869
|
+
identity: {
|
|
6870
|
+
displayName: project.displayName,
|
|
6871
|
+
aliases: project.aliases,
|
|
6872
|
+
canonicalDomain: project.canonicalDomain,
|
|
6873
|
+
ownedDomains: project.ownedDomains
|
|
6874
|
+
},
|
|
6875
|
+
country: project.country,
|
|
6876
|
+
language: project.language,
|
|
6877
|
+
location: runLocation ?? null,
|
|
6878
|
+
engines: activeProviders.map(({ adapter, config }) => ({
|
|
6879
|
+
provider: adapter.name,
|
|
6880
|
+
requestedModel: config.model ?? null
|
|
6881
|
+
})),
|
|
6882
|
+
// The legacy competitors table has domains only. Freeze the exact
|
|
6883
|
+
// identity we actually dispatched with so later reporting never
|
|
6884
|
+
// borrows renamed or newly added competitors from live project state.
|
|
6885
|
+
competitors: projectCompetitors.map((competitor) => {
|
|
6886
|
+
const label = brandLabelFromDomain(competitor.domain) || competitor.domain;
|
|
6887
|
+
return { domain: competitor.domain, label, aliases: [label] };
|
|
6888
|
+
}),
|
|
6889
|
+
queries: projectQueries.map((query) => ({
|
|
6890
|
+
queryId: query.id,
|
|
6891
|
+
queryText: query.query,
|
|
6892
|
+
provenance: query.provenance ?? null
|
|
6893
|
+
}))
|
|
6894
|
+
});
|
|
6895
|
+
captureSimpleMeasurementDefinition(this.db, { projectId, runId, definition });
|
|
6896
|
+
}
|
|
6863
6897
|
providerCallStart = Date.now();
|
|
6864
6898
|
if (planExecution) {
|
|
6865
6899
|
const plan = planExecution;
|
|
@@ -11869,7 +11903,7 @@ function readStoredGroundingSources(rawResponse) {
|
|
|
11869
11903
|
return result;
|
|
11870
11904
|
}
|
|
11871
11905
|
async function backfillInsightsCommand(project, opts) {
|
|
11872
|
-
const { IntelligenceService: IntelligenceService2 } = await import("./intelligence-service-
|
|
11906
|
+
const { IntelligenceService: IntelligenceService2 } = await import("./intelligence-service-BQIIWWQJ.js");
|
|
11873
11907
|
const config = loadConfig();
|
|
11874
11908
|
const db = createClient(config.database);
|
|
11875
11909
|
migrate(db);
|
|
@@ -16883,6 +16917,9 @@ function resolveDashboardRequirePassword(env, config) {
|
|
|
16883
16917
|
function resolveDashboardShowResourceLinks(env, config) {
|
|
16884
16918
|
return parseBooleanEnv(env.CANONRY_DASHBOARD_SHOW_RESOURCE_LINKS) ?? config.dashboard?.showResourceLinks ?? true;
|
|
16885
16919
|
}
|
|
16920
|
+
function resolveDashboardManagedSweeps(env, config) {
|
|
16921
|
+
return parseBooleanEnv(env.CANONRY_DASHBOARD_MANAGED_SWEEPS) ?? config.dashboard?.managedSweeps ?? false;
|
|
16922
|
+
}
|
|
16886
16923
|
function resolveDashboardShowUpdateNotification(env, config) {
|
|
16887
16924
|
return parseBooleanEnv(env.CANONRY_DASHBOARD_SHOW_UPDATE_NOTIFICATION) ?? config.dashboard?.showUpdateNotification ?? true;
|
|
16888
16925
|
}
|
|
@@ -18014,6 +18051,7 @@ async function createServer(opts) {
|
|
|
18014
18051
|
const dashboardRequirePassword = resolveDashboardRequirePassword(process.env, opts.config);
|
|
18015
18052
|
const dashboardShowResourceLinks = resolveDashboardShowResourceLinks(process.env, opts.config);
|
|
18016
18053
|
const dashboardShowUpdateNotification = resolveDashboardShowUpdateNotification(process.env, opts.config);
|
|
18054
|
+
const dashboardManagedSweeps = resolveDashboardManagedSweeps(process.env, opts.config);
|
|
18017
18055
|
const dashboardOnboardingMode = resolveDashboardOnboardingMode(process.env, opts.config);
|
|
18018
18056
|
app.log.info(
|
|
18019
18057
|
{ dashboardRequirePassword },
|
|
@@ -18904,6 +18942,9 @@ async function createServer(opts) {
|
|
|
18904
18942
|
if (!dashboardShowUpdateNotification) {
|
|
18905
18943
|
dashboardConfig.showUpdateNotification = false;
|
|
18906
18944
|
}
|
|
18945
|
+
if (dashboardManagedSweeps) {
|
|
18946
|
+
dashboardConfig.managedSweeps = true;
|
|
18947
|
+
}
|
|
18907
18948
|
if (!agentEnabled) {
|
|
18908
18949
|
dashboardConfig.showAgentBar = false;
|
|
18909
18950
|
}
|