@canonry/canonry 7.18.1 → 7.20.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (36) hide show
  1. package/assets/agent-workspace/skills/aero/references/agent-operations.md +14 -0
  2. package/assets/agent-workspace/skills/canonry/SKILL.md +14 -0
  3. package/assets/agent-workspace/skills/canonry/references/canonry-cli.md +33 -1
  4. package/assets/assets/AuditHistoryPanel-C0vj3liH.js +1 -0
  5. package/assets/assets/{BacklinksPage-BT3j4tQK.js → BacklinksPage-TnDsI9Wu.js} +1 -1
  6. package/assets/assets/{HistoryPage-BHV_3wbQ.js → HistoryPage-DEEC3g6M.js} +1 -1
  7. package/assets/assets/MeasurementPropertyPage-MT4tFOwx.js +4 -0
  8. package/assets/assets/ProjectPage-NI-bjpfN.js +8 -0
  9. package/assets/assets/{RunsPage-Cx5yMuzN.js → RunsPage-GIKqPu0J.js} +1 -1
  10. package/assets/assets/{SettingsPage-DrZ-eswp.js → SettingsPage-DLFwSj4J.js} +1 -1
  11. package/assets/assets/{SiteHealthSection-XOUI_75e.js → SiteHealthSection-CYG9IMh5.js} +3 -3
  12. package/assets/assets/{TrafficPage-DciX-fl5.js → TrafficPage-oOxDmxQq.js} +3 -3
  13. package/assets/assets/{TrafficSourceDetailPage-D1_lnRoS.js → TrafficSourceDetailPage-BGrwpVvM.js} +1 -1
  14. package/assets/assets/{extract-error-message-Cw5pcZtv.js → extract-error-message-DRDQFsgG.js} +1 -1
  15. package/assets/assets/{index-DIA9jvMi.js → index-B_2gPTCa.js} +36 -36
  16. package/assets/assets/{react-sigma_core.esm.min-Cc8jHlvQ.js → react-sigma_core.esm.min-DzDqz7hq.js} +1 -1
  17. package/assets/assets/v2-overview-adapter-BHzFliuj.js +1 -0
  18. package/assets/index.html +1 -1
  19. package/dist/{chunk-U7D7LNVJ.js → chunk-222NAFTY.js} +2 -2
  20. package/dist/{chunk-COQOQYRZ.js → chunk-46JZR2IV.js} +145 -31
  21. package/dist/{chunk-EAAM47H6.js → chunk-5IXQAOVK.js} +18 -3
  22. package/dist/{chunk-JUOFNJLV.js → chunk-6H2BC5EY.js} +3 -3
  23. package/dist/{chunk-PRL6UQ7L.js → chunk-KF7LRHGJ.js} +368 -211
  24. package/dist/{chunk-X2S7D3MN.js → chunk-MRKV43TV.js} +139 -7
  25. package/dist/{chunk-JMC7CEJB.js → chunk-NDQOCFJQ.js} +61 -43
  26. package/dist/cli.js +229 -45
  27. package/dist/{demo-server-XWRIXME5.js → demo-server-32PU7BM6.js} +4 -4
  28. package/dist/index.d.ts +1 -1
  29. package/dist/index.js +6 -6
  30. package/dist/{intelligence-service-332S7D7Y.js → intelligence-service-256DQBVR.js} +2 -2
  31. package/dist/mcp.js +4 -4
  32. package/package.json +13 -13
  33. package/assets/assets/AuditHistoryPanel-RAYlf3B4.js +0 -1
  34. package/assets/assets/MeasurementPropertyPage-9UFPKw-i.js +0 -1
  35. package/assets/assets/ProjectPage-C1_-qiHw.js +0 -8
  36. package/assets/assets/v2-overview-adapter-Ca5F20Kr.js +0 -1
@@ -1,4 +1,4 @@
1
- import{g as Bt,t as S,r as C}from"./vendor-tanstack-ZXXkndVj.js";import{e as Ht,G as Wt}from"./SiteHealthSection-XOUI_75e.js";import"./index-DIA9jvMi.js";import"./vendor-radix-twS1M3FF.js";import"./vendor-recharts-D-cUuLZo.js";import"./vendor-lucide-Y6jANGfG.js";import"./vendor-markdown-B4giJcws.js";import"./vendor-yaml-GWJz5H2G.js";import"./ChartPrimitives-CYlrwLJs.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-ZXXkndVj.js";import{e as Ht,G as Wt}from"./SiteHealthSection-CYG9IMh5.js";import"./index-B_2gPTCa.js";import"./vendor-radix-twS1M3FF.js";import"./vendor-recharts-D-cUuLZo.js";import"./vendor-lucide-Y6jANGfG.js";import"./vendor-markdown-B4giJcws.js";import"./vendor-yaml-GWJz5H2G.js";import"./ChartPrimitives-CYlrwLJs.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
@@ -0,0 +1 @@
1
+ import{r as C,j as i}from"./vendor-tanstack-ZXXkndVj.js";import{$ as de,e8 as pe,B as me,aJ as W,e9 as m,ea as fe,eb as ge,ec as he,ed as ye,ee as be,ef as xe,eg as ke,eh as Ae,ei as Pe,ej as je,ek as Ne,el as Ce,em as ve,en as Me,eo as Ie,ep as Be,eq as $e,er as Se,es as De,et as we,eu as Ke,ev as Ee,y as f,b5 as Ve}from"./index-B_2gPTCa.js";import{M as Re}from"./vendor-markdown-B4giJcws.js";import{C as Te,$ as qe,g as ne}from"./vendor-lucide-Y6jANGfG.js";const tt="Sources",_={copy:"Copy answer",copying:"Copying…",copied:"Copied",failed:"Could not copy. Select and copy the answer above."};function _e({previewLength:e,highlight:t}){return r=>{if(e!==void 0&&Number.isFinite(e)){let l=Math.max(0,Math.floor(e));const d={field:"value",omitted:!1},p=s=>{if(s.type==="definition")return!0;if(s.children)return s.children=s.children.filter(p),s.children.length>0;const a=s.type==="image"||s.type==="imageReference"?"alt":"value",h=s[a];if(h===void 0)return l>0;const k=Array.from(h);if(k.length===0)return l>0;if(l===0)return d.omitted=!0,!1;const v=k.length>l,j=k.slice(0,l);if(v&&!/\s/.test(k[l])){let y=j.length-1;for(;y>=0&&!/\s/.test(j[y]);)y--;y>=0&&y>l-40&&(j.length=y)}return d.omitted||=v,s[a]=j.join(""),l=v?0:l-j.length,j.length===0?!1:(d.lastNode=s,d.field=a,!0)};p(r),d.omitted&&(d.lastNode?d.lastNode[d.field]=`${d.lastNode[d.field].trimEnd()}…`:r.children?.push({type:"paragraph",children:[{type:"text",value:"…"}]}))}if(t){const l=d=>{["link","linkReference","code","inlineCode"].includes(d.type)||(d.type==="text"&&(d.data={...d.data,hName:"span"}),d.children?.forEach(l))};l(r)}}}function Ge({headingLevel:e}){return t=>{const r=[],l=p=>{p.type==="heading"&&p.depth&&r.push(p),p.children?.forEach(l)};l(t);const d=r.reduce((p,s)=>Math.min(p,s.depth),6);for(const p of r){const s=p.depth-d;p.depth=Math.min(6,e+s),p.data={...p.data,hProperties:{...p.data?.hProperties,"data-answer-heading-level":s+1}}}}}function Oe({answer:e}){const[t,r]=C.useState("idle"),l=C.useRef(!1),d=async()=>{if(!l.current){l.current=!0,r("copying");try{await navigator.clipboard.writeText(e),r("copied")}catch{r("failed")}finally{l.current=!1}}};return i.jsxs("div",{className:"mt-3 flex flex-wrap items-center gap-x-3",children:[i.jsx(me,{type:"button",variant:"ghost",className:"min-h-11 px-2","aria-disabled":t==="copying","aria-busy":t==="copying",onClick:()=>{d()},children:t==="copying"?_.copying:_.copy}),i.jsx("span",{role:"status",className:"text-sm text-secondary",children:t==="copied"?_.copied:t==="failed"?_.failed:""})]})}const nt=C.memo(function({children:t,headingLevel:r=4,copyable:l=!1,highlightGroups:d,previewLength:p}){return i.jsxs("div",{className:"answer-markdown",children:[i.jsx(Re,{remarkPlugins:[[Ge,{headingLevel:r}],[_e,{previewLength:p,highlight:!!d?.length}]],components:{p:({children:s})=>i.jsx("p",{className:"mb-3 whitespace-pre-wrap last:mb-0",children:s}),ul:({children:s})=>i.jsx("ul",{className:"mb-3 ml-5 list-disc space-y-1",children:s}),ol:({children:s,start:a})=>i.jsx("ol",{start:a,className:"mb-3 ml-5 list-decimal space-y-1",children:s}),pre:({children:s})=>i.jsx("pre",{className:"mb-3 overflow-x-auto whitespace-pre-wrap",children:s}),span:({children:s})=>i.jsx("span",{children:typeof s=="string"&&d?s.split(/(https?:\/\/[^\s<>]+)/i).map((a,h)=>h%2?a:i.jsx(C.Fragment,{children:pe(a,d)},h)):s}),a:({children:s,href:a})=>{const h=de(a);return h?i.jsx("a",{href:h,target:"_blank",rel:"noopener noreferrer",className:"text-link underline",children:s}):i.jsx("span",{children:s})},img:({alt:s})=>i.jsx("span",{children:s})},children:t}),l&&t.trim()?i.jsx(Oe,{answer:t},t):null]})}),re="min-h-11 w-full rounded-md border border-default bg-surface px-3 py-2 text-sm text-primary focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-mono-400",H="flex min-h-11 w-full items-center justify-between gap-3 rounded px-2 text-left text-sm text-primary hover:bg-surface-hover focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-mono-400",K=e=>e.kind==="project"?"Whole site":e.label,E={allMarkets:"All markets",browse:e=>`Browse ${e}`,select:e=>`Select ${e}`,browseAll:"Browse all properties"},Le=e=>e?.kind==="group"&&e.marketKeys?.length===1?e.marketKeys[0]:void 0,se=e=>`${e} ${e===1?"property":"properties"}`;function rt({options:e,selected:t,onSelect:r,marketKey:l,label:d="Measurement scope",labelVisibility:p="visible",allowGroupSelect:s=!0}){const a=[...e].sort((n,u)=>n.label.localeCompare(u.label,void 0,{numeric:!0})||n.id.localeCompare(u.id)),[h,k]=C.useState(""),[v,j]=C.useState([]),[y,I]=C.useState(!1),N=C.useRef(null),B=C.useRef(null),o=C.useId(),x=a.filter(n=>n.kind==="group"),b=new Map(x.map(n=>[n.id,n])),c=b.get(v.at(-1)??""),Y=b.get(v.at(-2)??""),P=h.trim().toLocaleLowerCase(),le=x.filter(n=>!n.parentGroupIds?.some(u=>b.has(u))),G=a.filter(n=>n.kind==="property"),O=n=>(n.parentGroupIds??[]).map(u=>b.get(u)?.label).filter(Boolean).join(" · "),V=n=>`${K(n)} ${O(n)}`.toLocaleLowerCase().includes(P),z=n=>{const u=[...n.parentGroupIds??[]],g=new Set;for(;u.length;){const M=u.pop();if(M===c?.id)return!0;g.has(M)||(g.add(M),u.push(...b.get(M)?.parentGroupIds??[]))}return!1},S=(y?[]:c?x.filter(n=>P?z(n):n.parentGroupIds?.includes(c.id)):P?x:le).filter(V),D=a.find(n=>n.kind==="market"&&n.id===(l??(t.kind==="market"?t.id:void 0))),Q=c&&D&&(c.marketKeys?.includes(D.id)||D.parentGroupIds?.includes(c.id))?D.id:void 0,L=s?Q??Le(c):void 0,U=(c?G.filter(n=>n.parentGroupIds?.includes(c.id)&&(!L||n.marketKeys?.includes(L))):P||y||x.length===0?G:[]).filter(V),J=a.filter(n=>n.kind!=="market"||y||!s&&!c&&!P&&x.length>0||s&&c?.marketKeys?.length===1&&!P?!1:(c?P?z(n):n.parentGroupIds?.includes(c.id):P||!n.parentGroupIds?.some(g=>b.has(g)))&&V(n)),Z=c||y?[]:a.filter(n=>n.kind==="project"&&V(n));C.useEffect(()=>{const n=u=>{N.current?.open&&u.target instanceof Node&&!N.current.contains(u.target)&&(N.current.open=!1)};return document.addEventListener("pointerdown",n),()=>document.removeEventListener("pointerdown",n)},[]);const ce=n=>{N.current&&(N.current.open=!1,N.current.querySelector("summary")?.focus());const u=s?n.kind==="property"?L:n.kind==="group"&&n.id===c?.id?Q:void 0:void 0;u?r(n,u):r(n)},R=n=>{const u=[];let g=b.get(n.parentGroupIds?.[0]??"");for(;g&&!u.includes(g.id)&&g.id!==n.id;)u.unshift(g.id),g=b.get(g.parentGroupIds?.[0]??"");return[...u,n.id]},ue=()=>{const n=t.kind==="group"?b.get(t.id):void 0,u=b.get(D?.parentGroupIds?.[0]??""),g=(t.parentGroupIds??[]).flatMap(w=>{const q=b.get(w);return q?[R(q)]:[]}),M=g.find(w=>w.at(-1)===c?.id)??g.sort((w,q)=>q.length-w.length)[0]??[],te=u?R(u):t.marketKeys?.length?[]:M;j(n?R(n):te),I(t.kind==="property"&&te.length===0&&x.length>0),k("")},X=n=>{j(R(n)),I(!1),k(""),B.current?.focus()},T=(n,u=K(n))=>i.jsxs("div",{className:"flex items-stretch",children:[i.jsxs("button",{type:"button",className:H,"aria-label":n.kind==="group"&&!s?E.browse(K(n)):E.select(K(n)),"aria-current":t.kind===n.kind&&t.id===n.id?"true":void 0,onClick:()=>n.kind==="group"&&!s?X(n):ce(n),children:[i.jsxs("span",{className:"min-w-0 break-words",children:[u,P&&O(n)?i.jsx("span",{className:"block text-[13px] text-secondary",children:O(n)}):null]}),i.jsx("span",{className:"shrink-0 text-right text-[13px] text-secondary",children:n.kind==="market"?s?"Query context":"Market":n.kind==="property"?"Property":se(n.targetCount)})]}),s&&n.kind==="group"&&n.id!==c?.id&&a.some(g=>g.parentGroupIds?.includes(n.id))?i.jsx("button",{type:"button","aria-label":E.browse(n.label),title:`Browse ${n.label}`,className:"flex min-h-11 min-w-11 items-center justify-center rounded text-secondary hover:bg-surface-hover focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-mono-400",onClick:()=>X(n),children:i.jsx(ne,{size:18,"aria-hidden":"true"})}):null]},`${n.kind}:${n.id}`),F=(n,u)=>u.length>0?i.jsxs("section",{"aria-label":n,className:"mt-2",children:[i.jsx("h3",{className:"px-2 py-2 text-[13px] font-medium text-secondary",children:n}),u.map(g=>T(g))]}):null,ee=(n,u,g)=>u.length>0?i.jsxs("details",{open:g,className:"mt-2 border-y border-default",children:[i.jsxs("summary",{className:"min-h-11 cursor-pointer px-2 py-3 text-sm text-primary focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-mono-400",children:[n," (",u.length,")"]}),u.map(M=>T(M))]},`${c?.id??"root"}:${n}`):null;return i.jsxs("div",{className:"min-w-0",children:[i.jsx("span",{id:`${o}-label`,className:p==="sr-only"?"sr-only":"mb-1 block text-sm font-medium text-heading",children:d}),i.jsxs("details",{ref:N,className:"relative",onToggle:n=>{n.target===n.currentTarget&&n.currentTarget.open&&B.current?.focus()},onKeyDown:n=>{n.key==="Escape"&&(n.preventDefault(),n.currentTarget.open=!1,n.currentTarget.querySelector("summary")?.focus())},children:[i.jsxs("summary",{id:`${o}-value`,"aria-labelledby":`${o}-label ${o}-value`,className:`${re} visibility-scope-trigger`,onClick:()=>{N.current?.open||ue()},children:[`${K(t)}${t.kind==="group"?` · ${se(t.targetCount)}`:t.kind==="property"?` · ${a.find(n=>n.kind==="market"&&n.id===l)?.label??(t.marketKeys?.length?E.allMarkets:"Property")}`:t.kind==="market"?" · Market":""}`,i.jsx(Te,{size:16,"aria-hidden":"true",className:"shrink-0 text-secondary"})]}),i.jsxs("div",{className:"visibility-scope-menu",children:[c||y?i.jsxs("div",{className:"mb-2 border-b border-default pb-2",children:[i.jsx("button",{type:"button",className:H,"aria-label":`Back to ${Y?.label??"all groups"}`,onClick:()=>{j(v.slice(0,-1)),I(!1),k(""),B.current?.focus()},children:i.jsxs("span",{className:"flex items-center gap-1",children:[i.jsx(qe,{size:16,"aria-hidden":"true"}),Y?.label??"All groups"]})}),i.jsx("p",{className:"px-2 py-1 text-sm font-medium text-heading","aria-live":"polite",children:c?.label??"All properties"})]}):null,i.jsx("input",{ref:B,type:"search","aria-label":"Search scopes",className:re,placeholder:c?"Search within this group":y?"Search properties":"Search groups or properties",value:h,onChange:n=>k(n.target.value)}),i.jsxs("div",{className:"mt-2 max-h-80 overflow-y-auto",children:[s&&c&&!P?T(c,"All properties in this group"):null,Z.map(n=>T(n)),c&&!P?ee("Subgroups",S,!0):F(c?"Subgroups":"Groups",S),P?F("Properties",U):ee(c&&S.length>0?"All properties":"Properties",U,!c||S.length===0),F("Markets",J),!c&&!y&&!P&&x.length>0&&G.length>0?i.jsxs("button",{type:"button",className:`${H} mt-2 border-t border-default`,"aria-label":E.browseAll,onClick:()=>{I(!0),B.current?.focus()},children:[i.jsx("span",{children:"All properties"}),i.jsx(ne,{size:18,"aria-hidden":"true"})]}):null,P&&S.length+U.length+J.length+Z.length===0?i.jsx("p",{className:"py-3 text-sm text-secondary",children:"No matching scopes."}):null]})]})]})]})}function oe(){return typeof crypto<"u"&&typeof crypto.randomUUID=="function"?crypto.randomUUID():`web-${Date.now()}-${Math.random().toString(36).slice(2)}`}function A(e){return{"If-Match":e,"Idempotency-Key":oe()}}function st(e){return e instanceof W&&(e.statusCode===404||e.statusCode===409||e.statusCode===412)}function at(e,t){return e instanceof W?t:(e instanceof Error?e.message.trim():"")||t}function it(e){const t="Could not calculate assignment impact.";if(!(e instanceof W)||e.code!=="VALIDATION_ERROR")return t;const r=e.message.trim();return e.details?.displayToOperator===!0&&r?r:t}const ot={loadSetup:e=>m(()=>Ee({client:f,path:{name:e}})),loadDraft:e=>m(()=>Ke({client:f,path:{name:e}})),createDraft:(e,t)=>m(()=>we({client:f,path:{name:e},headers:{"Idempotency-Key":oe()},body:{expectedActiveRevision:t}})),importSitemap:(e,t,r)=>m(()=>De({client:f,path:{name:e},headers:A(t),body:r})),applySitemapSelection:(e,t,r,l)=>m(()=>Se({client:f,path:{name:e},headers:A(t),body:{selections:r,selectedTargetKeys:l}})),previewAssignments:(e,t)=>m(()=>$e({client:f,path:{name:e},body:t})),applyAssignments:(e,t,r)=>m(()=>Be({client:f,path:{name:e},headers:A(t),body:r})),replaceAssignments:(e,t,r)=>m(()=>Ie({client:f,path:{name:e},headers:A(t),body:r})),applyPairedAssignments:(e,t,r)=>m(()=>Me({client:f,path:{name:e},headers:A(t),body:{pairs:r}})),removeAssignment:(e,t,r,l)=>m(()=>ve({client:f,path:{name:e},headers:A(t),body:{targetKeys:r,queryId:l}})),excludeTarget:(e,t,r)=>m(()=>Ce({client:f,path:{name:e},headers:A(t),body:{targetKey:r,cleanup:"assignments-and-group-memberships"}})),upsertTarget:(e,t,r)=>m(()=>Ne({client:f,path:{name:e},headers:A(t),body:{target:r}})),upsertGroup:(e,t,r)=>m(()=>je({client:f,path:{name:e},headers:A(t),body:{group:r}})),removeGroup:(e,t,r)=>m(()=>Pe({client:f,path:{name:e},headers:A(t),body:{groupKey:r}})),upsertCompetitor:(e,t,r)=>m(()=>Ae({client:f,path:{name:e},headers:A(t),body:r})),removeCompetitor:(e,t,r,l)=>m(()=>ke({client:f,path:{name:e},headers:A(t),body:{groupKey:r,competitorKey:l}})),previewGroupMembership:(e,t)=>m(()=>xe({client:f,path:{name:e},body:t})),applyGroupMembership:(e,t,r)=>m(()=>be({client:f,path:{name:e},headers:A(t),body:r})),compilePreview:e=>m(()=>ye({client:f,path:{name:e}})),diffPreview:e=>m(()=>he({client:f,path:{name:e}})),publish:(e,t,r)=>m(()=>ge({client:f,path:{name:e},headers:A(t),body:r})),discard:(e,t)=>m(()=>fe({client:f,path:{name:e},headers:A(t)}))};function lt(e){const t=e[0];return t?e.every(r=>r.mode===t.mode&&r.scope.kind===t.scope.kind&&r.scope.key===t.scope.key&&r.queryClass===t.queryClass&&r.measurement.displayedRunId===t.measurement.displayedRunId):!0}function $(e){return e.state==="unavailable"?{numerator:null,denominator:null,reason:e.reason}:e.numerator===void 0||e.denominator===void 0||e.denominator<=0?{numerator:null,denominator:null,reason:"not_applicable"}:{numerator:e.numerator,denominator:e.denominator,...e.unattributed===void 0?{}:{unattributed:e.unattributed},...e.unchecked===void 0?{}:{unchecked:e.unchecked}}}function Ue(e){return e.kind==="exact"?e.url:e.kind==="prefix"?`https://${e.host}${e.pathPrefix}/*`:`https://${e.host}/*`}function Fe(e){return e==="assigned"?"this-property":e==="sibling"?"another-property":e==="ownedUnmapped"?"owned-unassigned":e==="external"?"external":e==="ambiguous"?"multiple-properties":"invalid-url"}function He(e){return e==="assigned"?"positive":e==="external"?"neutral":e==="invalid"?"negative":"caution"}function ae(e){return`target:${e.targetKey}:${e.queryId}:${e.executionNodeKey}`}function We(e,t,r){const l=new Map;if(!t)return l;const d=new Map(e.usageEdges.map(a=>[ae(a),a.targetKey])),p=new Map(e.assignments.map(a=>[`${a.targetKey}:${a.queryId}`,a.queryClass])),s=new Map(e.usageEdges.map(a=>[ae(a),p.get(`${a.targetKey}:${a.queryId}`)]));for(const a of t.evidence){if(r&&s.get(a.usageEdgeId)!==r)continue;const h=d.get(a.usageEdgeId);if(!h)continue;const k=l.get(h)??[];k.push({id:`${a.observationId}:${a.expectedSlotId}:${a.usageEdgeId}:${a.sourceUrl}`,kind:Fe(a.classification),query:a.queryText,provider:a.provider,location:a.location,url:a.sourceUrl,tone:He(a.classification),historical:a.historical||a.bridged}),l.set(h,k)}return l}function Ye(e){if(e.flags>0)return{label:"Review",tone:"caution"};const t=[e.mentionCoverage,e.citationCoverage].filter(r=>r.state==="unavailable").map(r=>r.reason);return t.includes("no_completed_run")?{label:"Not measured",tone:"neutral"}:t.includes("plan_v1")?{label:"Update setup",tone:"caution"}:t.includes("evidence_incomplete")?{label:"Evidence incomplete",tone:"caution"}:t.includes("identity_ambiguous")?{label:Ve.ambiguous,tone:"caution"}:t.includes("no_population")?{label:"No queries",tone:"neutral"}:t.includes("not_applicable")?{label:"Not applicable",tone:"neutral"}:{label:"Complete",tone:"positive"}}function ze(e){return e==="complete"?{label:"Complete",tone:"positive"}:e==="partial"?{label:"Partial",tone:"caution"}:e==="queued"?{label:"Queued",tone:"neutral"}:e==="running"?{label:"Running",tone:"neutral"}:e==="failed"?{label:"Failed",tone:"negative"}:{label:"Not measured",tone:"neutral"}}function Qe(e){if(!e)return"";const t=new Date(e);return Number.isFinite(t.getTime())?t.toLocaleDateString("en-US",{month:"short",day:"numeric",year:"numeric",timeZone:"UTC"}):""}function ie(e){const t=e.nextAction.count??e.flags.total;if(e.nextAction.kind==="review_flags")return`${t} flagged ${t===1?"result needs":"results need"} review.`;if(e.nextAction.kind==="complete_setup")return"Finish setup.";if(e.nextAction.kind==="republish_setup")return"Setup update required.";if(e.nextAction.kind==="run_measurement")return"Ready to measure."}function ct({overview:e,activePlan:t,report:r,reportState:l=r?"ready":"loading",sort:d}){if(t.plan.schemaVersion!==2||e.mode!=="active-v2")throw new Error("The current overview requires an active version-two setup.");if(e.scope.kind!=="all"&&e.scope.kind!=="group")throw new Error("The current overview requires an All Properties or group scope.");const p=t.plan,s=new Map(p.targets.map(o=>[o.stableKey,o])),a=new Map(p.querySnapshots.map(o=>[o.queryId,o.queryText])),h=new Map;for(const o of p.assignments){if(e.queryClass!=="all"&&o.queryClass!==e.queryClass)continue;const x=a.get(o.queryId);if(!x)continue;const b=h.get(o.targetKey)??new Set;b.add(x),h.set(o.targetKey,b)}const k=r?.revision===t.revision&&r.run?.id===e.measurement.displayedRunId?r:null,v=e.measurement.displayedRunId===void 0||k?"ready":l==="error"||r!=null?"error":"loading",j=We(p,k,e.queryClass==="all"?void 0:e.queryClass),y=new Map;for(const o of p.groups)for(const x of o.targetKeys)y.has(x)||y.set(x,o.label);const I=e.properties.items.map(o=>{const x=s.get(o.targetKey),b=j.get(o.targetKey)??[];return{id:o.targetKey,name:o.label,mentionCoverage:$(o.mentionCoverage),citationCoverage:$(o.citationCoverage),status:Ye(o),providers:o.providers?.map(c=>({provider:c.provider,mentionCoverage:$(c.mentionCoverage),citationCoverage:$(c.citationCoverage)})),market:y.get(o.targetKey),assignedQueries:[...h.get(o.targetKey)??[]],urls:x?.urlMatchers.map(Ue)??[],evidence:b,evidenceState:v,historical:b.some(c=>c.historical)}}),N=e.namedShareOfVoice?.entries.map(o=>({name:o.label,coverage:{numerator:o.credits,denominator:e.namedShareOfVoice.denominator}})),B=e.properties.items.flatMap(o=>o.flags>0?[{id:`property:${o.targetKey}`,property:o.label,summary:`${o.flags} ${o.flags===1?"result needs":"results need"} review.`,tone:"caution",count:o.flags}]:[]);return{classReporting:"available",latestMeasurement:{status:ze(e.measurement.state),completedSlots:e.measurement.completed,totalSlots:e.measurement.expected,date:Qe(e.measurement.completedAt),includesBridgedHistory:e.measurement.includesHistoricalData===!0},currentView:{scope:e.scope.kind==="group"?{kind:"group",...e.scope.key?{key:e.scope.key}:{}}:{kind:"all"},queryClass:e.queryClass,aggregate:{metrics:{propertiesMentioned:$(e.metrics.propertiesMentioned),mentionCoverage:$(e.metrics.mentionCoverage),citationCoverage:$(e.metrics.citationCoverage)},properties:I,...N?{shareOfVoice:N}:{}},propertyTotal:e.properties.totalEstimate??I.length,outcomes:e.outcomes,nextCursor:e.properties.nextCursor,...d?{sort:d}:{}},availableGroups:p.groups.map(o=>({id:o.stableKey,label:o.label})),...ie(e)?{nextActionText:ie(e)}:{},flaggedResultsTotal:e.flags.total,flaggedResults:B}}export{nt as A,E as M,rt as V,tt as a,ot as b,it as c,lt as d,ct as e,st as i,Ue as m,at as s};
package/assets/index.html CHANGED
@@ -12,7 +12,7 @@
12
12
  <link rel="icon" type="image/png" sizes="32x32" href="./favicon-32.png" />
13
13
  <link rel="apple-touch-icon" href="./apple-touch-icon.png" />
14
14
  <title>Canonry</title>
15
- <script type="module" crossorigin src="./assets/index-DIA9jvMi.js"></script>
15
+ <script type="module" crossorigin src="./assets/index-B_2gPTCa.js"></script>
16
16
  <link rel="modulepreload" crossorigin href="./assets/vendor-tanstack-ZXXkndVj.js">
17
17
  <link rel="modulepreload" crossorigin href="./assets/vendor-radix-twS1M3FF.js">
18
18
  <link rel="modulepreload" crossorigin href="./assets/vendor-recharts-D-cUuLZo.js">
@@ -5,7 +5,7 @@ import {
5
5
  siteCrawlGraphNodes,
6
6
  siteCrawlPages,
7
7
  siteCrawlSnapshots
8
- } from "./chunk-COQOQYRZ.js";
8
+ } from "./chunk-46JZR2IV.js";
9
9
  import {
10
10
  SITE_CRAWL_GRAPH_MAX_EDGES,
11
11
  SITE_CRAWL_GRAPH_MAX_NODES,
@@ -15,7 +15,7 @@ import {
15
15
  factorStatusFromDistribution,
16
16
  factorStatusFromScore,
17
17
  roundPreservingTotal
18
- } from "./chunk-X2S7D3MN.js";
18
+ } from "./chunk-MRKV43TV.js";
19
19
 
20
20
  // src/site-audit-factors.ts
21
21
  function recordedSharePct(factor) {
@@ -556,6 +556,8 @@ import {
556
556
  measurementDraftUpsertTargetRequestSchema,
557
557
  measurementIdempotencyKeyConflict,
558
558
  measurementIdempotencyKeyRequired,
559
+ measurementNameKey,
560
+ measurementNameWords,
559
561
  measurementOverviewQuerySchema,
560
562
  measurementOverviewResponseSchema,
561
563
  measurementOverviewSortSchema,
@@ -599,6 +601,8 @@ import {
599
601
  measurementSegmentRetirementResponseSchema,
600
602
  measurementSetupResponseSchema,
601
603
  measurementStableKeySchema,
604
+ measurementTargetNameIssueMessage,
605
+ measurementTargetNameIssues,
602
606
  measurementV2UsageEdgeKey,
603
607
  mentionStateFromAnswerMentioned,
604
608
  missingDependency,
@@ -660,8 +664,11 @@ import {
660
664
  providerAuthError,
661
665
  providerDispatchModeSchema,
662
666
  providerError,
667
+ providerReloadRequestSchema,
668
+ providerReloadResponseDtoSchema,
663
669
  providerSummaryEntryDtoSchema,
664
670
  providersFailing,
671
+ qualifiedNameIncludesName,
665
672
  queryDtoSchema,
666
673
  queryGenerateRequestSchema,
667
674
  queryGenerateResponseSchema,
@@ -848,7 +855,7 @@ import {
848
855
  wordpressSchemaDeployResultDtoSchema,
849
856
  wordpressSchemaStatusResultDtoSchema,
850
857
  wordpressStatusDtoSchema
851
- } from "./chunk-X2S7D3MN.js";
858
+ } from "./chunk-MRKV43TV.js";
852
859
 
853
860
  // src/intelligence-service.ts
854
861
  import { eq as eq89, desc as desc41, asc as asc18, and as and75, ne as ne16, or as or22, inArray as inArray36, gte as gte24, lte as lte20, isNull as isNull17, sql as sql32, exists as exists2 } from "drizzle-orm";
@@ -15856,6 +15863,24 @@ async function settingsRoutes(app, opts) {
15856
15863
  }
15857
15864
  return result;
15858
15865
  });
15866
+ app.post("/settings/providers/reload", async (request) => {
15867
+ requireScope(request, SETTINGS_WRITE_SCOPE);
15868
+ requireInstanceAdministrator(request);
15869
+ const parsed = providerReloadRequestSchema.safeParse(request.body ?? {});
15870
+ if (!parsed.success) {
15871
+ throw validationError("Invalid provider reload request", parsed.error.flatten());
15872
+ }
15873
+ if (!opts.onProviderReload) {
15874
+ throw notImplemented("Provider configuration reload is not supported in this deployment");
15875
+ }
15876
+ const { actor, userAgent, actorSession, requestId, credentialId } = auditFromRequest(request, {
15877
+ actor: "api",
15878
+ action: "providers.reloaded",
15879
+ entityType: "provider"
15880
+ });
15881
+ const providers = await opts.onProviderReload(parsed.data, { actor, userAgent, actorSession, requestId, credentialId });
15882
+ return providerReloadResponseDtoSchema.parse({ reloaded: true, providers });
15883
+ });
15859
15884
  app.put("/settings/google", async (request) => {
15860
15885
  requireScope(request, SETTINGS_WRITE_SCOPE);
15861
15886
  const { clientId, clientSecret } = request.body ?? {};
@@ -16090,11 +16115,9 @@ function normalizeMeasurementLocation(value) {
16090
16115
  if (value === null) return null;
16091
16116
  return normalizeIdentityText(value) || null;
16092
16117
  }
16093
- function words(value) {
16094
- return value.normalize("NFKC").toLowerCase().match(/[\p{L}\p{N}]+/gu) ?? [];
16095
- }
16118
+ var words = measurementNameWords;
16096
16119
  function measurementMentionAliasKey(value) {
16097
- return words(value).join("\0");
16120
+ return measurementNameKey(value);
16098
16121
  }
16099
16122
  function aliasMatchesAt(textWords, aliasWords, start) {
16100
16123
  if (aliasWords.length === 0 || start + aliasWords.length > textWords.length) return false;
@@ -17665,10 +17688,10 @@ function providerSettingsChangeCouldFix(action, diff) {
17665
17688
  try {
17666
17689
  const parsed = JSON.parse(diff ?? "null");
17667
17690
  if (!parsed) return false;
17668
- if (parsed.apiKeyRotated) return true;
17691
+ if (parsed.apiKeyRotated || parsed.credentialsChanged) return true;
17669
17692
  const before = parsed.before ?? {};
17670
17693
  const after = parsed.after ?? {};
17671
- return before.configured !== after.configured || before.model !== after.model || before.baseUrl !== after.baseUrl;
17694
+ return before.configured !== after.configured || before.model !== after.model || before.baseUrl !== after.baseUrl || before.vertexProject !== after.vertexProject || before.vertexRegion !== after.vertexRegion;
17672
17695
  } catch {
17673
17696
  return false;
17674
17697
  }
@@ -23305,11 +23328,8 @@ function compileMeasurementDraft(authoring, context) {
23305
23328
  aliasClaims.set(identity, target.stableKey);
23306
23329
  });
23307
23330
  const aliases = sortedUnique(target.aliases);
23308
- const aliasKeys = aliases.map(measurementMentionAliasKey).filter(Boolean);
23309
23331
  target.identityAliases?.forEach((identityAlias, index2) => {
23310
- const identityKey = measurementMentionAliasKey(identityAlias);
23311
- const qualifiesAlias = aliasKeys.some((aliasKey) => identityKey !== aliasKey && `\0${identityKey}\0`.includes(`\0${aliasKey}\0`));
23312
- if (!qualifiesAlias) {
23332
+ if (!qualifiedNameIncludesName(identityAlias, aliases)) {
23313
23333
  sink.fail("target-identity-alias-unqualified", "An identity phrase must include a Property alias and additional identifying context.", ["targets", targetIndex, "identityAliases", index2]);
23314
23334
  }
23315
23335
  });
@@ -23827,13 +23847,18 @@ function withRequestedContext(assignment, contextOverride) {
23827
23847
  const { executionContexts: _frozenContexts, ...withoutFrozenContexts } = assignment;
23828
23848
  return { ...withoutFrozenContexts, contextOverride };
23829
23849
  }
23830
- function upsertTarget(authoring, body) {
23850
+ function upsertTarget(authoring, body, context) {
23831
23851
  const { target } = parseBody2(measurementDraftUpsertTargetRequestSchema, body, "upsert-target");
23832
23852
  const index2 = authoring.targets.findIndex((candidate) => candidate.stableKey === target.stableKey);
23833
23853
  const targets = [...authoring.targets];
23834
23854
  if (index2 === -1) targets.push(target);
23835
23855
  else targets[index2] = target;
23836
- return { authoring: { ...authoring, targets }, warnings: [] };
23856
+ const warnings = measurementTargetNameIssues({
23857
+ aliases: target.aliases,
23858
+ ...target.identityAliases === void 0 ? {} : { identityAliases: target.identityAliases },
23859
+ brandNames: context.brandNames
23860
+ }).map((issue) => warn(issue.code, measurementTargetNameIssueMessage(issue), ["target", issue.field, issue.index]));
23861
+ return { authoring: { ...authoring, targets }, warnings };
23837
23862
  }
23838
23863
  function renameTarget(authoring, body) {
23839
23864
  const { targetKey, label } = parseBody2(measurementDraftRenameTargetRequestSchema, body, "rename-target");
@@ -24156,7 +24181,7 @@ function applyDraftAction(action, authoring, body, context) {
24156
24181
  const result = (() => {
24157
24182
  switch (action) {
24158
24183
  case "upsert-target":
24159
- return upsertTarget(authoring, body);
24184
+ return upsertTarget(authoring, body, context);
24160
24185
  case "rename-target":
24161
24186
  return renameTarget(authoring, body);
24162
24187
  case "merge-targets":
@@ -26635,6 +26660,9 @@ function capSources(row) {
26635
26660
  function answerRowKey(row) {
26636
26661
  return [row.expectedSlotId, row.usageEdgeId].join("\0");
26637
26662
  }
26663
+ function otherQueryRowKey(row) {
26664
+ return [row.expectedSlotId, row.queryClass].join("\0");
26665
+ }
26638
26666
  function encodeCursor(cursor) {
26639
26667
  const { shape, ...rest } = cursor;
26640
26668
  return Buffer.from(
@@ -26653,7 +26681,7 @@ function parseCursor2(value) {
26653
26681
  if (typeof candidate !== "string" || candidate.length === 0) return null;
26654
26682
  }
26655
26683
  const shape = cursor.shape === void 0 ? MEASUREMENT_EVIDENCE_DEFAULT_SHAPE : cursor.shape;
26656
- if (shape !== MeasurementEvidenceShapes.sources && shape !== MeasurementEvidenceShapes.answers) return null;
26684
+ if (shape !== MeasurementEvidenceShapes.sources && shape !== MeasurementEvidenceShapes.answers && shape !== MeasurementEvidenceShapes["other-queries"]) return null;
26657
26685
  return {
26658
26686
  v: 1,
26659
26687
  key: cursor.key,
@@ -26686,12 +26714,57 @@ function propertyEvidenceRows(db, plan, active, run, query, queryClass) {
26686
26714
  const location = query.location === void 0 ? void 0 : normalizeMeasurementLocation(query.location);
26687
26715
  const owned = (row) => ownEdgeIds.has(row.usageEdgeId) && (provider === void 0 || row.provider === provider) && (location === void 0 || normalizeMeasurementLocation(row.location) === location);
26688
26716
  const built = buildMeasurementEvidence(input);
26717
+ const narrowed = (row) => (provider === void 0 || row.provider === provider) && (location === void 0 || normalizeMeasurementLocation(row.location) === location);
26689
26718
  return {
26690
26719
  sources: built.evidence.filter(owned),
26691
26720
  answers: built.answers.filter(owned),
26721
+ otherQueries: otherQueryCitations(input.usageEdges, built.answers, query.targetKey, queryClass).filter(narrowed),
26692
26722
  evidenceFingerprint: snapshotEvidenceFingerprint(snapshots)
26693
26723
  };
26694
26724
  }
26725
+ function otherQueryCitations(usageEdges, answers, targetKey, queryClass) {
26726
+ const edgesByExecution = /* @__PURE__ */ new Map();
26727
+ for (const edge of usageEdges) {
26728
+ if (edge.type !== "target") continue;
26729
+ const edges = edgesByExecution.get(edge.executionId) ?? [];
26730
+ edges.push({ targetId: edge.targetId, queryClass: edge.queryClass ?? null });
26731
+ edgesByExecution.set(edge.executionId, edges);
26732
+ }
26733
+ const rows = [];
26734
+ const seen2 = /* @__PURE__ */ new Set();
26735
+ for (const answer of answers) {
26736
+ if (seen2.has(answer.expectedSlotId)) continue;
26737
+ seen2.add(answer.expectedSlotId);
26738
+ const edges = edgesByExecution.get(answer.executionId) ?? [];
26739
+ if (edges.some((edge) => edge.targetId === targetKey)) continue;
26740
+ const own = answer.sources.filter((source) => source.classification === "sibling" && source.matchedTargetIds.length === 1 && source.matchedTargetIds[0] === targetKey);
26741
+ if (own.length === 0) continue;
26742
+ const sources = own.map((source) => ({
26743
+ sourceUrl: source.sourceUrl,
26744
+ normalizedUrl: source.normalizedUrl,
26745
+ matchedUrlIds: source.matchedUrlIds
26746
+ }));
26747
+ const classes = sortedUnique(edges.flatMap((edge) => edge.queryClass === null ? [] : [edge.queryClass]));
26748
+ for (const edgeClass of classes) {
26749
+ if (queryClass !== "all" && edgeClass !== queryClass) continue;
26750
+ rows.push({
26751
+ observationId: answer.observationId,
26752
+ expectedSlotId: answer.expectedSlotId,
26753
+ executionId: answer.executionId,
26754
+ provider: answer.provider,
26755
+ queryText: answer.queryText,
26756
+ location: answer.location,
26757
+ queryClass: edgeClass,
26758
+ assignedTargetKeys: sortedUnique(edges.filter((edge) => edge.queryClass === edgeClass).map((edge) => edge.targetId)),
26759
+ sources: sources.slice(0, MAX_SOURCES_PER_ANSWER),
26760
+ sourceCount: sources.length,
26761
+ sourcesTruncated: sources.length > MAX_SOURCES_PER_ANSWER,
26762
+ evidenceComplete: answer.evidenceComplete
26763
+ });
26764
+ }
26765
+ }
26766
+ return rows;
26767
+ }
26695
26768
  function pageOf2(rows, keyOf, shape, query, displayedRunId, planVersionId, evidenceFingerprint) {
26696
26769
  const limit = query.limit ?? MEASUREMENT_PAGE_DEFAULT_LIMIT;
26697
26770
  let offset = 0;
@@ -26766,10 +26839,10 @@ async function measurementPropertyEvidenceRoutes(app) {
26766
26839
  // The page still arrives under the key the caller's shape names. An
26767
26840
  // unmeasured Property has no rows in EITHER reading, and swapping the
26768
26841
  // key here would read as "that shape is unavailable" instead.
26769
- ...shape === MeasurementEvidenceShapes.answers ? { answers: empty } : { evidence: empty }
26842
+ ...shape === MeasurementEvidenceShapes.answers ? { answers: empty } : shape === MeasurementEvidenceShapes["other-queries"] ? { otherQueries: empty } : { evidence: empty }
26770
26843
  });
26771
26844
  }
26772
- const { sources, answers, evidenceFingerprint } = propertyEvidenceRows(app.db, plan, active, displayed, query, queryClass);
26845
+ const { sources, answers, otherQueries, evidenceFingerprint } = propertyEvidenceRows(app.db, plan, active, displayed, query, queryClass);
26773
26846
  const pageArgs = [shape, query, displayed.id, active.version.id, evidenceFingerprint];
26774
26847
  return measurementPropertyEvidenceResponseSchema.parse({
26775
26848
  property,
@@ -26779,7 +26852,7 @@ async function measurementPropertyEvidenceRoutes(app) {
26779
26852
  displayedRunId: displayed.id,
26780
26853
  ...displayed.finishedAt ? { completedAt: displayed.finishedAt } : {}
26781
26854
  },
26782
- ...shape === MeasurementEvidenceShapes.answers ? { answers: pageOf2(answers.map(capSources), answerRowKey, ...pageArgs) } : { evidence: pageOf2(sources, sourceRowKey, ...pageArgs) }
26855
+ ...shape === MeasurementEvidenceShapes.answers ? { answers: pageOf2(answers.map(capSources), answerRowKey, ...pageArgs) } : shape === MeasurementEvidenceShapes["other-queries"] ? { otherQueries: pageOf2(otherQueries, otherQueryRowKey, ...pageArgs) } : { evidence: pageOf2(sources, sourceRowKey, ...pageArgs) }
26783
26856
  });
26784
26857
  }
26785
26858
  );
@@ -28761,11 +28834,17 @@ function targetPresence(candidates, targets, targetKey) {
28761
28834
  const values = scoped.map((candidate) => targetValues(candidate, targets, targetKey));
28762
28835
  const citations = scoped.map((candidate, index2) => candidate.observation?.citationComplete === false ? null : values[index2].citation);
28763
28836
  const anyKnown = (signals) => signals.includes(true) ? true : signals.length === 0 || signals.includes(null) ? null : false;
28837
+ const mention = anyKnown(values.map((value) => value.mention));
28838
+ const citation = anyKnown(citations);
28764
28839
  return {
28765
28840
  targetKey,
28766
- mention: anyKnown(values.map((value) => value.mention)),
28767
- citation: anyKnown(citations),
28768
- identityAmbiguous: values.some((value) => value.mentionUnavailableReason === "identity-ambiguous")
28841
+ mention,
28842
+ citation,
28843
+ identityAmbiguous: values.some((value) => value.mentionUnavailableReason === "identity-ambiguous"),
28844
+ // Every answer was saved, so an unknown citation can only come from an
28845
+ // answer whose source list was partly saved. With the mention measured,
28846
+ // that is the one reason this Property reads not measured.
28847
+ uncheckedOnly: mention !== null && citation === null && scoped.length > 0 && scoped.every((candidate) => candidate.observation !== null)
28769
28848
  };
28770
28849
  }
28771
28850
  function outcomeCounts(rows) {
@@ -28785,6 +28864,19 @@ function outcomeCounts(rows) {
28785
28864
  }
28786
28865
  return counts2;
28787
28866
  }
28867
+ function uncheckedSourceEvidence(rows) {
28868
+ const unchecked = rows.filter((candidate) => candidate.observation !== null && !candidate.observation.citationComplete);
28869
+ if (unchecked.length === 0) return void 0;
28870
+ const cited = unchecked.map((candidate) => {
28871
+ const edgeTargets = new Set(candidate.edges.map((edge) => edge.targetKey));
28872
+ return candidate.observation.citedTargetKeys.filter((key) => edgeTargets.has(key));
28873
+ });
28874
+ return {
28875
+ answers: unchecked.length,
28876
+ citedAnswers: cited.filter((keys) => keys.length > 0).length,
28877
+ citedTargetKeys: sortedUnique(cited.flat())
28878
+ };
28879
+ }
28788
28880
  function coverageSummary(candidates, definition, targets = targetMap(definition)) {
28789
28881
  const unique3 = new Map(candidates.map((candidate) => [candidateKey(candidate), candidate]));
28790
28882
  const rows = [...unique3.values()];
@@ -28807,13 +28899,15 @@ function summary2(candidates, definition, populationTargetKeys = selectedTargetK
28807
28899
  eligibleTargets.length,
28808
28900
  eligibleTargets.some((row) => row.mention === null && row.identityAmbiguous) ? "identity-ambiguous" : "evidence-incomplete"
28809
28901
  );
28902
+ const notMeasuredUnchecked = targetRows.filter((row) => row.uncheckedOnly).length;
28810
28903
  return {
28811
28904
  queryCount: base.queryCount,
28812
28905
  answerCount: base.answerCount,
28813
28906
  mentionCoverage: base.mentionCoverage,
28814
28907
  citationCoverage: base.citationCoverage,
28815
28908
  propertyReach,
28816
- outcomes: outcomeCounts(targetRows)
28909
+ outcomes: outcomeCounts(targetRows),
28910
+ ...notMeasuredUnchecked > 0 ? { notMeasuredUnchecked } : {}
28817
28911
  };
28818
28912
  }
28819
28913
  function queryRows(candidates, definition, selection) {
@@ -28830,6 +28924,7 @@ function queryRows(candidates, definition, selection) {
28830
28924
  return [...groups.values()].map((rows) => {
28831
28925
  const first = rows[0];
28832
28926
  const value = coverageSummary(rows, definition, targets);
28927
+ const uncheckedSources = uncheckedSourceEvidence(value.rows);
28833
28928
  return {
28834
28929
  sourceSnapshotIds: sortedUnique(rows.flatMap((row) => row.observation ? [row.observation.answerId] : [])),
28835
28930
  queryKey: first.slot.queryKey,
@@ -28845,7 +28940,8 @@ function queryRows(candidates, definition, selection) {
28845
28940
  })(),
28846
28941
  answerCount: value.answerCount,
28847
28942
  mentionCoverage: value.mentionCoverage,
28848
- citationCoverage: value.citationCoverage
28943
+ citationCoverage: value.citationCoverage,
28944
+ ...uncheckedSources === void 0 ? {} : { uncheckedSources }
28849
28945
  };
28850
28946
  }).sort((left, right) => (selection.scope === "property" && selection.marketKey === void 0 ? compareText((left.marketKeys ?? []).join("\0"), (right.marketKeys ?? []).join("\0")) : 0) || compareText(normalizeIdentityText(left.query), normalizeIdentityText(right.query)) || compareText(left.provider, right.provider) || compareText(left.model ?? "", right.model ?? "") || compareText(left.location ?? "", right.location ?? "") || compareText(left.queryKey, right.queryKey));
28851
28947
  }
@@ -38592,6 +38688,8 @@ var SCHEMA_TABLE = {
38592
38688
  ProjectOverviewDto: projectOverviewDtoSchema,
38593
38689
  TrafficAnalyticsResponse: trafficAnalyticsResponseSchema,
38594
38690
  ProjectSearchResponseDto: projectSearchResponseSchema,
38691
+ ProviderReloadRequest: providerReloadRequestSchema,
38692
+ ProviderReloadResponseDto: providerReloadResponseDtoSchema,
38595
38693
  ProviderSummaryEntryDto: providerSummaryEntryDtoSchema,
38596
38694
  QueryDto: queryDtoSchema,
38597
38695
  QueryGenerateResponse: queryGenerateResponseSchema,
@@ -39284,8 +39382,8 @@ var measurementOverviewCursorParameter = {
39284
39382
  var measurementPropertyEvidenceShapeParameter = {
39285
39383
  name: "shape",
39286
39384
  in: "query",
39287
- description: "What one row is. sources (the default) returns one row per cited URL under evidence, which is what a caller written before this parameter existed reads. answers returns one row per measured answer under answers, with the cited URLs nested inside it, so the answers that cited nothing at all are present rather than missing. Exactly one of the two keys is returned; the other is absent, not empty.",
39288
- schema: { type: "string", enum: ["sources", "answers"], default: "sources" }
39385
+ description: "What one row is. sources (the default) returns one row per cited URL under evidence, which is what a caller written before this parameter existed reads. answers returns one row per measured answer under answers, with the cited URLs nested inside it, so the answers that cited nothing at all are present rather than missing. other-queries returns, under otherQueries, one row per answer to a query NOT assigned to this Property that cited one of its own pages, per assignment class; those answers are outside its rates. Exactly one of the keys is returned; the others are absent, not empty.",
39386
+ schema: { type: "string", enum: ["sources", "answers", "other-queries"], default: "sources" }
39289
39387
  };
39290
39388
  var measurementPropertyEvidenceCursorParameter = {
39291
39389
  name: "cursor",
@@ -39995,7 +40093,7 @@ var routeCatalog = [
39995
40093
  method: "get",
39996
40094
  path: "/api/v1/projects/{name}/measurement-property-evidence",
39997
40095
  summary: "Page one Property's evidence",
39998
- description: "Returns the evidence rows for exactly one Property out of one revision-pinned run, optionally narrowed to a question class, provider, or location. shape chooses what a row is: sources (the default) is one row per cited URL, answers is one row per measured answer with its cited URLs nested inside. Prefer answers to explain a gap \u2014 an answer that mentioned the Property without linking it, or that named nobody, has no URL to hang a source row on and is invisible in the default shape. Run selection matches the overview: the most recent completed run pinned to the active revision unless runId names another. Use this rather than GET /measurement-report when you want one Property \u2014 the report reconstructs every group and Target for a revision and does not paginate. Not available for a schema v1 revision, which records no question class to scope by. An empty page under measurement.state = not_measured means the Property has not been measured, which is not the same statement as a measured Property with no evidence.",
40096
+ description: "Returns the evidence rows for exactly one Property out of one revision-pinned run, optionally narrowed to a question class, provider, or location. shape chooses what a row is: sources (the default) is one row per cited URL, answers is one row per measured answer with its cited URLs nested inside, other-queries is one row per answer to a query not assigned to this Property that cited its pages (outside its rates). Prefer answers to explain a gap \u2014 an answer that mentioned the Property without linking it, or that named nobody, has no URL to hang a source row on and is invisible in the default shape. Run selection matches the overview: the most recent completed run pinned to the active revision unless runId names another. Use this rather than GET /measurement-report when you want one Property \u2014 the report reconstructs every group and Target for a revision and does not paginate. Not available for a schema v1 revision, which records no question class to scope by. An empty page under measurement.state = not_measured means the Property has not been measured, which is not the same statement as a measured Property with no evidence.",
39999
40097
  tags: ["measurement-plans"],
40000
40098
  parameters: [
40001
40099
  nameParameter,
@@ -41430,6 +41528,21 @@ var routeCatalog = [
41430
41528
  501: errorResponse("Provider updates are not supported.")
41431
41529
  }
41432
41530
  },
41531
+ {
41532
+ method: "post",
41533
+ path: "/api/v1/settings/providers/reload",
41534
+ summary: "Reload saved provider configuration",
41535
+ description: "Requires settings.write and install administrator authority. Reloads only the execution host's own saved provider configuration, including credentials, models, quotas and batch settings. Returns credential-free provider status. Optional configPath and databasePath are an identity pair: supply both or neither. They must match the host's captured paths and never select an arbitrary file; a pair naming another install returns VALIDATION_ERROR with error.details.reason install-identity-mismatch. A config the host boots with also reloads, with the same registrations. No provider calls are made. Unsupported hosts return NOT_IMPLEMENTED.",
41536
+ tags: ["settings"],
41537
+ requestBody: { required: false, content: { "application/json": { schema: { $ref: "#/components/schemas/ProviderReloadRequest" } } } },
41538
+ responses: {
41539
+ 200: jsonResponse("Saved provider configuration is active.", "ProviderReloadResponseDto"),
41540
+ 400: errorResponse("Invalid reload request, unloadable config, or install identity mismatch (error.details.reason install-identity-mismatch)."),
41541
+ 403: errorResponse("Install administrator authority is required."),
41542
+ 409: errorResponse("Outstanding provider batch work requires the current registration. Quota-only changes remain available."),
41543
+ 501: errorResponse("Provider reload is not supported.")
41544
+ }
41545
+ },
41433
41546
  {
41434
41547
  method: "put",
41435
41548
  path: "/api/v1/settings/google",
@@ -85632,7 +85745,7 @@ var providersConfiguredCheck = {
85632
85745
  status: CheckStatuses.warn,
85633
85746
  code: "providers.none-configured",
85634
85747
  summary: "No answer-engine provider is configured. Page Health remains available; AI Visibility is disabled.",
85635
- remediation: "To enable AI Visibility, set a provider environment variable and rerun `canonry bootstrap`, or run `canonry settings provider <name> --api-key <key>` while the server is running.",
85748
+ remediation: "To enable AI Visibility, run `canonry settings provider <name> --api-key <key>` while the server is running, or set a provider environment variable and rerun `canonry bootstrap`. Bootstrap reloads a matching running local server; if it is offline, start it to use the saved settings.",
85636
85749
  details: { available: summary3.map((entry) => entry.name) }
85637
85750
  };
85638
85751
  }
@@ -90208,7 +90321,7 @@ async function researchRoutes(app, opts) {
90208
90321
  }
90209
90322
  if (!opts.onResearchRunRequested) throw missingDependency("Research execution is not available on this deployment.", { reason: "no-research-handler" });
90210
90323
  const adapters = opts.providerAdapters ?? [];
90211
- const configured = new Set(opts.configuredProviderNames ?? []);
90324
+ const configured = new Set(opts.getConfiguredProviderNames?.() ?? opts.configuredProviderNames ?? []);
90212
90325
  const providerName = input.provider ?? project.providers.find((name) => configured.has(name) && adapters.some((adapter2) => adapter2.name === name && adapter2.mode === "api")) ?? adapters.find((adapter2) => adapter2.mode === "api" && configured.has(adapter2.name))?.name;
90213
90326
  const adapter = adapters.find((candidate) => candidate.name === providerName);
90214
90327
  if (!providerName || !adapter || adapter.mode !== "api" || isBrowserProvider(providerName) || !configured.has(providerName)) throw validationError("Research requires a configured API provider.", { provider: input.provider, validProviders: adapters.filter((a) => a.mode === "api" && configured.has(a.name)).map((a) => a.name) });
@@ -90356,7 +90469,7 @@ async function researchRoutes(app, opts) {
90356
90469
  const runs2 = rows.slice(0, limit).map(serializeRun);
90357
90470
  const last = runs2.at(-1);
90358
90471
  const nextCursor = rows.length > limit && last ? Buffer.from(JSON.stringify({ projectId: project.id, createdAt: last.createdAt, id: last.id })).toString("base64url") : null;
90359
- const configured = new Set(opts.configuredProviderNames ?? []);
90472
+ const configured = new Set(opts.getConfiguredProviderNames?.() ?? opts.configuredProviderNames ?? []);
90360
90473
  const effectiveModels2 = opts.getEffectiveProviderModels?.() ?? {};
90361
90474
  const providers = (opts.providerAdapters ?? []).filter((adapter) => adapter.mode === "api" && !isBrowserProvider(adapter.name) && configured.has(adapter.name)).map((adapter) => {
90362
90475
  const defaultModel = resolveProviderModel(adapter.name, project.providerModels[adapter.name] || effectiveModels2[adapter.name] || adapter.defaultModel);
@@ -90428,7 +90541,7 @@ function researchBatchRequestHash(input) {
90428
90541
  }
90429
90542
  function prepareBatchRun(app, opts, project, active, input) {
90430
90543
  const adapters = opts.providerAdapters ?? [];
90431
- const configured = new Set(opts.configuredProviderNames ?? []);
90544
+ const configured = new Set(opts.getConfiguredProviderNames?.() ?? opts.configuredProviderNames ?? []);
90432
90545
  const providerName = input.provider;
90433
90546
  const adapter = adapters.find((candidate) => candidate.name === providerName);
90434
90547
  if (!adapter || adapter.mode !== "api" || isBrowserProvider(providerName) || !configured.has(providerName)) {
@@ -90942,6 +91055,7 @@ async function apiRoutes(app, opts) {
90942
91055
  providerSummary: opts.providerSummary,
90943
91056
  providerAdapters: opts.providerAdapters,
90944
91057
  onProviderUpdate: opts.onProviderUpdate,
91058
+ onProviderReload: opts.onProviderReload,
90945
91059
  google: opts.googleSettingsSummary,
90946
91060
  onGoogleUpdate: opts.onGoogleSettingsUpdate,
90947
91061
  bing: opts.bingSettingsSummary,
@@ -91076,7 +91190,7 @@ async function apiRoutes(app, opts) {
91076
91190
  getCachedProviderModels: opts.getCachedProviderModels,
91077
91191
  getEffectiveProviderModels: opts.getEffectiveProviderModels,
91078
91192
  providerAdapters: opts.providerAdapters,
91079
- configuredProviderNames: opts.providerSummary?.filter((provider) => provider.configured).map((provider) => provider.name),
91193
+ getConfiguredProviderNames: () => opts.getRunnableProviderNames?.() ?? opts.providerSummary?.filter((provider) => provider.configured).map((provider) => provider.name) ?? [],
91080
91194
  onResearchRunRequested: opts.onResearchRunRequested,
91081
91195
  allowViewers: opts.researchAllowViewers,
91082
91196
  viewerDailyRunLimit: opts.researchViewerDailyRunLimit
@@ -99,6 +99,8 @@ import {
99
99
  projectConfigSchema,
100
100
  projectUpsertRequestSchema,
101
101
  providerQuotaPolicySchema,
102
+ providerReloadRequestSchema,
103
+ providerReloadResponseDtoSchema,
102
104
  providerSummaryEntryDtoSchema,
103
105
  queryBatchRequestSchema,
104
106
  queryClassSchema,
@@ -142,7 +144,7 @@ import {
142
144
  trafficSeriesGranularitySchema,
143
145
  visibilityCompareSelectionSchema,
144
146
  visibilityReportRequestSchema
145
- } from "./chunk-X2S7D3MN.js";
147
+ } from "./chunk-MRKV43TV.js";
146
148
 
147
149
  // src/cli-error.ts
148
150
  function isMachineFormat(format) {
@@ -446,7 +448,7 @@ var measurementPropertyEvidenceInputSchema = measurementPropertyEvidenceQuerySch
446
448
  targetKey: measurementPropertyEvidenceQuerySchema.shape.targetKey.describe("Property stable key. Required \u2014 this read is scoped to exactly one Property."),
447
449
  queryClass: propertyQueryClassInputSchema,
448
450
  shape: measurementPropertyEvidenceQuerySchema.shape.shape.describe(
449
- "What one row is. Omit for sources (one row per cited URL). answers gives one row per measured answer with its cited URLs nested, including the answers that cited nothing."
451
+ "What one row is. Omit for sources (one row per cited URL). answers gives one row per measured answer with its cited URLs nested, including the answers that cited nothing. other-queries gives one row per answer to a query NOT assigned to this Property that cited one of its own pages; those answers are outside its rates."
450
452
  )
451
453
  }).strict();
452
454
  var measurementPortfolioSummaryInputSchema = measurementPortfolioSummaryQuerySchema.extend({
@@ -2127,6 +2129,19 @@ var canonryMcpTools = [
2127
2129
  openApiOperations: ["PUT /api/v1/settings/providers/{name}"],
2128
2130
  handler: async (client, { provider, ...request }) => client.updateProvider(provider, request)
2129
2131
  }),
2132
+ defineTool({
2133
+ name: "canonry_providers_reload",
2134
+ title: "Reload saved provider configuration",
2135
+ description: "With explicit operator approval, reload the connected server's saved provider credentials, models, quotas and batch settings without restarting it. Requires install administrator authority and settings.write. Accepts no credentials. Optional configPath and databasePath must be supplied together and match the server's own install; they never select another file. Returns credential-free provider status and makes no provider calls. Unsupported deployments return NOT_IMPLEMENTED.",
2136
+ access: "write",
2137
+ requiredScope: "settings.write",
2138
+ tier: "setup",
2139
+ inputSchema: providerReloadRequestSchema,
2140
+ outputSchema: providerReloadResponseDtoSchema,
2141
+ annotations: writeAnnotations({ idempotentHint: true }),
2142
+ openApiOperations: ["POST /api/v1/settings/providers/reload"],
2143
+ handler: (client, input) => client.reloadProviders(input)
2144
+ }),
2130
2145
  defineTool({
2131
2146
  name: "canonry_telemetry_get",
2132
2147
  requiresOperator: true,
@@ -2938,7 +2953,7 @@ var canonryMcpTools = [
2938
2953
  defineTool({
2939
2954
  name: "canonry_measurement_property_evidence",
2940
2955
  title: "Page one Property's measurement evidence",
2941
- description: "Return the stored evidence rows for exactly one Property out of one revision-pinned run, optionally narrowed to a provider or location. Defaults to non-brand queries; pass queryClass branded or all to change it, and state the returned class. shape chooses what a row is: sources (the default) returns one row per cited URL under evidence; answers returns one row per measured answer under answers, with the cited URLs nested inside and both signals on the row (mentioned, cited). Use shape=answers to explain a GAP: an answer that mentioned the Property without linking it, or that named nobody at all, has no URL to hang a source row on and does not appear in the default shape, so counting source rows understates what was measured. mentioned is null, never false, when the answer text was never captured: that is a missing signal, not a measured no. Exactly one of evidence or answers is returned and the other is absent rather than empty. A cursor is bound to the shape that issued it and is refused on the other. Prefer this over canonry_measurement_report when you want one Property: the report reconstructs every group and every Target for a revision and does not paginate. Run selection matches canonry_measurement_overview: the most recent completed run pinned to the active revision unless runId names another, and a run pinned to a different revision is refused rather than joined. The cursor also pins the active revision, displayed run, evidence snapshot, and filters; reuse it unchanged. Not available for a schema v1 revision, which records no question class to scope by. It never starts provider work; page size is at most 100. An empty page under measurement.state = not_measured means the Property has not been measured at all, which is NOT a measured result of zero.",
2956
+ description: "Return the stored evidence rows for exactly one Property out of one revision-pinned run, optionally narrowed to a provider or location. Defaults to non-brand queries; pass queryClass branded or all to change it, and state the returned class. shape chooses what a row is: sources (the default) returns one row per cited URL under evidence; answers returns one row per measured answer under answers, with the cited URLs nested inside and both signals on the row (mentioned, cited). Use shape=answers to explain a GAP: an answer that mentioned the Property without linking it, or that named nobody at all, has no URL to hang a source row on and does not appear in the default shape, so counting source rows understates what was measured. shape=other-queries returns, under otherQueries, answers to queries assigned only to other Properties that still cited this Property's pages, one row per answer and assignment class with assignedTargetKeys; never add them to its rates. mentioned is null, never false, when the answer text was never captured: that is a missing signal, not a measured no. Exactly one of evidence, answers or otherQueries is returned and the others are absent rather than empty. A cursor is bound to the shape that issued it and is refused on the other. Prefer this over canonry_measurement_report when you want one Property: the report reconstructs every group and every Target for a revision and does not paginate. Run selection matches canonry_measurement_overview: the most recent completed run pinned to the active revision unless runId names another, and a run pinned to a different revision is refused rather than joined. The cursor also pins the active revision, displayed run, evidence snapshot, and filters; reuse it unchanged. Not available for a schema v1 revision, which records no question class to scope by. It never starts provider work; page size is at most 100. An empty page under measurement.state = not_measured means the Property has not been measured at all, which is NOT a measured result of zero.",
2942
2957
  access: "read",
2943
2958
  tier: "setup",
2944
2959
  inputSchema: measurementPropertyEvidenceInputSchema,
@@ -4,14 +4,14 @@ import {
4
4
  installSkills,
5
5
  loadConfigRaw,
6
6
  saveConfigPatch
7
- } from "./chunk-JMC7CEJB.js";
7
+ } from "./chunk-NDQOCFJQ.js";
8
8
  import {
9
9
  PACKAGE_VERSION
10
- } from "./chunk-EAAM47H6.js";
10
+ } from "./chunk-5IXQAOVK.js";
11
11
  import {
12
12
  SKILL_MANIFEST_FILENAME,
13
13
  SkillsClients
14
- } from "./chunk-X2S7D3MN.js";
14
+ } from "./chunk-MRKV43TV.js";
15
15
 
16
16
  // src/skills-autosync.ts
17
17
  import fs from "fs";