@canonry/canonry 4.164.1 → 4.165.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/agent-workspace/skills/canonry/references/canonry-cli.md +4 -1
- package/assets/assets/{AuditHistoryPanel-m4hLLnEl.js → AuditHistoryPanel-IYMElyK5.js} +1 -1
- package/assets/assets/{BacklinksPage-DWl04vdm.js → BacklinksPage-BMqIPRvZ.js} +1 -1
- package/assets/assets/{HistoryPage-BTb0MBB4.js → HistoryPage-iuETLmwO.js} +1 -1
- package/assets/assets/{MeasurementPropertyPage-C8c4huVf.js → MeasurementPropertyPage-BzNAaB8X.js} +1 -1
- package/assets/assets/{ProjectPage-CEbscgtB.js → ProjectPage-DIzi4Ggo.js} +1 -1
- package/assets/assets/{RunRow-CDzkoy89.js → RunRow-BkkYxEjl.js} +1 -1
- package/assets/assets/{RunsPage-CzLCTfIA.js → RunsPage-DGTrqrTA.js} +1 -1
- package/assets/assets/{SettingsPage-D8Vfdd2n.js → SettingsPage-Cwb_Ft9u.js} +1 -1
- package/assets/assets/{SiteHealthSection-BGmBOTo0.js → SiteHealthSection-k4I71wfJ.js} +3 -3
- package/assets/assets/{TrafficPage-BcmemZJB.js → TrafficPage-C8nyb8l1.js} +1 -1
- package/assets/assets/{TrafficSourceDetailPage-B9Dz1vcn.js → TrafficSourceDetailPage-ry7Da0pV.js} +1 -1
- package/assets/assets/{extract-error-message-B5tyCXha.js → extract-error-message-BYyBW07F.js} +1 -1
- package/assets/assets/{index-CEjDqng5.js → index-rqOXhYwp.js} +13 -13
- package/assets/assets/{react-sigma_core.esm.min-z4XxmpWJ.js → react-sigma_core.esm.min-BtG8TWTe.js} +1 -1
- package/assets/index.html +1 -1
- package/dist/{chunk-DCCEKIJ7.js → chunk-BU6C2DKF.js} +10 -0
- package/dist/{chunk-XYZMJA3L.js → chunk-L5SMSDZB.js} +4 -4
- package/dist/{chunk-76DCR646.js → chunk-QDOZEMDK.js} +29 -1
- package/dist/{chunk-R6QOYKRW.js → chunk-QKLNTSQ2.js} +142 -4
- package/dist/cli.js +40 -7
- package/dist/index.js +4 -4
- package/dist/{intelligence-service-5UVHKSHR.js → intelligence-service-RDGUEEZQ.js} +2 -2
- package/dist/mcp.js +2 -2
- package/package.json +8 -8
package/assets/assets/{react-sigma_core.esm.min-z4XxmpWJ.js → react-sigma_core.esm.min-BtG8TWTe.js}
RENAMED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{g as Bt,t as S,r as C}from"./vendor-tanstack-Dock0eH1.js";import{e as Ht,G as Wt}from"./SiteHealthSection-
|
|
1
|
+
import{g as Bt,t as S,r as C}from"./vendor-tanstack-Dock0eH1.js";import{e as Ht,G as Wt}from"./SiteHealthSection-k4I71wfJ.js";import"./index-rqOXhYwp.js";import"./vendor-radix-4UOaVWza.js";import"./vendor-recharts-D8rt5lKn.js";import"./vendor-lucide-nYKv-BB7.js";import"./vendor-markdown-Bn7fRwrx.js";import"./vendor-yaml-GWJz5H2G.js";import"./ChartPrimitives-BoYe2M-i.js";function Vt(r,n){if(typeof r!="object"||!r)return r;var i=r[Symbol.toPrimitive];if(i!==void 0){var e=i.call(r,n);if(typeof e!="object")return e;throw new TypeError("@@toPrimitive must return a primitive value.")}return String(r)}function ae(r){var n=Vt(r,"string");return typeof n=="symbol"?n:n+""}function A(r,n){if(!(r instanceof n))throw new TypeError("Cannot call a class as a function")}function He(r,n){for(var i=0;i<n.length;i++){var e=n[i];e.enumerable=e.enumerable||!1,e.configurable=!0,"value"in e&&(e.writable=!0),Object.defineProperty(r,ae(e.key),e)}}function L(r,n,i){return n&&He(r.prototype,n),i&&He(r,i),Object.defineProperty(r,"prototype",{writable:!1}),r}function Q(r){return Q=Object.setPrototypeOf?Object.getPrototypeOf.bind():function(n){return n.__proto__||Object.getPrototypeOf(n)},Q(r)}function yt(){try{var r=!Boolean.prototype.valueOf.call(Reflect.construct(Boolean,[],function(){}))}catch{}return(yt=function(){return!!r})()}function jt(r){if(r===void 0)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return r}function Zt(r,n){if(n&&(typeof n=="object"||typeof n=="function"))return n;if(n!==void 0)throw new TypeError("Derived constructors may only return object or undefined");return jt(r)}function I(r,n,i){return n=Q(n),Zt(r,yt()?Reflect.construct(n,i||[],Q(r).constructor):n.apply(r,i))}function xe(r,n){return xe=Object.setPrototypeOf?Object.setPrototypeOf.bind():function(i,e){return i.__proto__=e,i},xe(r,n)}function G(r,n){if(typeof n!="function"&&n!==null)throw new TypeError("Super expression must either be null or a function");r.prototype=Object.create(n&&n.prototype,{constructor:{value:r,writable:!0,configurable:!0}}),Object.defineProperty(r,"prototype",{writable:!1}),n&&xe(r,n)}function qt(r){if(Array.isArray(r))return r}function Yt(r,n){var i=r==null?null:typeof Symbol<"u"&&r[Symbol.iterator]||r["@@iterator"];if(i!=null){var e,t,a,o,s=[],l=!0,h=!1;try{if(a=(i=i.call(r)).next,n===0){if(Object(i)!==i)return;l=!1}else for(;!(l=(e=a.call(i)).done)&&(s.push(e.value),s.length!==n);l=!0);}catch(u){h=!0,t=u}finally{try{if(!l&&i.return!=null&&(o=i.return(),Object(o)!==o))return}finally{if(h)throw t}}return s}}function Se(r,n){(n==null||n>r.length)&&(n=r.length);for(var i=0,e=Array(n);i<n;i++)e[i]=r[i];return e}function Tt(r,n){if(r){if(typeof r=="string")return Se(r,n);var i={}.toString.call(r).slice(8,-1);return i==="Object"&&r.constructor&&(i=r.constructor.name),i==="Map"||i==="Set"?Array.from(r):i==="Arguments"||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(i)?Se(r,n):void 0}}function Xt(){throw new TypeError(`Invalid attempt to destructure non-iterable instance.
|
|
2
2
|
In order to be iterable, non-array objects must have a [Symbol.iterator]() method.`)}function ee(r,n){return qt(r)||Yt(r,n)||Tt(r,n)||Xt()}var pe={black:"#000000",silver:"#C0C0C0",gray:"#808080",grey:"#808080",white:"#FFFFFF",maroon:"#800000",red:"#FF0000",purple:"#800080",fuchsia:"#FF00FF",green:"#008000",lime:"#00FF00",olive:"#808000",yellow:"#FFFF00",navy:"#000080",blue:"#0000FF",teal:"#008080",aqua:"#00FFFF",darkblue:"#00008B",mediumblue:"#0000CD",darkgreen:"#006400",darkcyan:"#008B8B",deepskyblue:"#00BFFF",darkturquoise:"#00CED1",mediumspringgreen:"#00FA9A",springgreen:"#00FF7F",cyan:"#00FFFF",midnightblue:"#191970",dodgerblue:"#1E90FF",lightseagreen:"#20B2AA",forestgreen:"#228B22",seagreen:"#2E8B57",darkslategray:"#2F4F4F",darkslategrey:"#2F4F4F",limegreen:"#32CD32",mediumseagreen:"#3CB371",turquoise:"#40E0D0",royalblue:"#4169E1",steelblue:"#4682B4",darkslateblue:"#483D8B",mediumturquoise:"#48D1CC",indigo:"#4B0082",darkolivegreen:"#556B2F",cadetblue:"#5F9EA0",cornflowerblue:"#6495ED",rebeccapurple:"#663399",mediumaquamarine:"#66CDAA",dimgray:"#696969",dimgrey:"#696969",slateblue:"#6A5ACD",olivedrab:"#6B8E23",slategray:"#708090",slategrey:"#708090",lightslategray:"#778899",lightslategrey:"#778899",mediumslateblue:"#7B68EE",lawngreen:"#7CFC00",chartreuse:"#7FFF00",aquamarine:"#7FFFD4",skyblue:"#87CEEB",lightskyblue:"#87CEFA",blueviolet:"#8A2BE2",darkred:"#8B0000",darkmagenta:"#8B008B",saddlebrown:"#8B4513",darkseagreen:"#8FBC8F",lightgreen:"#90EE90",mediumpurple:"#9370DB",darkviolet:"#9400D3",palegreen:"#98FB98",darkorchid:"#9932CC",yellowgreen:"#9ACD32",sienna:"#A0522D",brown:"#A52A2A",darkgray:"#A9A9A9",darkgrey:"#A9A9A9",lightblue:"#ADD8E6",greenyellow:"#ADFF2F",paleturquoise:"#AFEEEE",lightsteelblue:"#B0C4DE",powderblue:"#B0E0E6",firebrick:"#B22222",darkgoldenrod:"#B8860B",mediumorchid:"#BA55D3",rosybrown:"#BC8F8F",darkkhaki:"#BDB76B",mediumvioletred:"#C71585",indianred:"#CD5C5C",peru:"#CD853F",chocolate:"#D2691E",tan:"#D2B48C",lightgray:"#D3D3D3",lightgrey:"#D3D3D3",thistle:"#D8BFD8",orchid:"#DA70D6",goldenrod:"#DAA520",palevioletred:"#DB7093",crimson:"#DC143C",gainsboro:"#DCDCDC",plum:"#DDA0DD",burlywood:"#DEB887",lightcyan:"#E0FFFF",lavender:"#E6E6FA",darksalmon:"#E9967A",violet:"#EE82EE",palegoldenrod:"#EEE8AA",lightcoral:"#F08080",khaki:"#F0E68C",aliceblue:"#F0F8FF",honeydew:"#F0FFF0",azure:"#F0FFFF",sandybrown:"#F4A460",wheat:"#F5DEB3",beige:"#F5F5DC",whitesmoke:"#F5F5F5",mintcream:"#F5FFFA",ghostwhite:"#F8F8FF",salmon:"#FA8072",antiquewhite:"#FAEBD7",linen:"#FAF0E6",lightgoldenrodyellow:"#FAFAD2",oldlace:"#FDF5E6",magenta:"#FF00FF",deeppink:"#FF1493",orangered:"#FF4500",tomato:"#FF6347",hotpink:"#FF69B4",coral:"#FF7F50",darkorange:"#FF8C00",lightsalmon:"#FFA07A",orange:"#FFA500",lightpink:"#FFB6C1",pink:"#FFC0CB",gold:"#FFD700",peachpuff:"#FFDAB9",navajowhite:"#FFDEAD",moccasin:"#FFE4B5",bisque:"#FFE4C4",mistyrose:"#FFE4E1",blanchedalmond:"#FFEBCD",papayawhip:"#FFEFD5",lavenderblush:"#FFF0F5",seashell:"#FFF5EE",cornsilk:"#FFF8DC",lemonchiffon:"#FFFACD",floralwhite:"#FFFAF0",snow:"#FFFAFA",lightyellow:"#FFFFE0",ivory:"#FFFFF0"},Ct=new Int8Array(4),be=new Int32Array(Ct.buffer,0,1),$t=new Float32Array(Ct.buffer,0,1),Kt=/^\s*rgba?\s*\(/,Jt=/^\s*rgba?\s*\(\s*([0-9]*)\s*,\s*([0-9]*)\s*,\s*([0-9]*)(?:\s*,\s*(.*)?)?\)\s*$/;function Qt(r){var n=0,i=0,e=0,t=1;if(r[0]==="#")r.length===4?(n=parseInt(r.charAt(1)+r.charAt(1),16),i=parseInt(r.charAt(2)+r.charAt(2),16),e=parseInt(r.charAt(3)+r.charAt(3),16)):(n=parseInt(r.charAt(1)+r.charAt(2),16),i=parseInt(r.charAt(3)+r.charAt(4),16),e=parseInt(r.charAt(5)+r.charAt(6),16)),r.length===9&&(t=parseInt(r.charAt(7)+r.charAt(8),16)/255);else if(Kt.test(r)){var a=r.match(Jt);a&&(n=+a[1],i=+a[2],e=+a[3],a[4]&&(t=+a[4]))}return{r:n,g:i,b:e,a:t}}var J={};for(var le in pe)J[le]=oe(pe[le]),J[pe[le]]=J[le];function Rt(r,n,i,e,t){return be[0]=e<<24|i<<16|n<<8|r,be[0]=be[0]&4278190079,$t[0]}function oe(r){if(r=r.toLowerCase(),typeof J[r]<"u")return J[r];var n=Qt(r),i=n.r,e=n.g,t=n.b,a=n.a;a=a*255|0;var o=Rt(i,e,t,a);return J[r]=o,o}var Ee={};function _t(r){if(typeof Ee[r]<"u")return Ee[r];var n=(r&16711680)>>>16,i=(r&65280)>>>8,e=r&255,t=255,a=Rt(n,i,e,t);return Ee[r]=a,a}function We(r,n,i,e){return i+(n<<8)+(r<<16)}function Ve(r,n,i,e,t,a){var o=Math.floor(i/a*t),s=Math.floor(r.drawingBufferHeight/a-e/a*t),l=new Uint8Array(4);r.bindFramebuffer(r.FRAMEBUFFER,n),r.readPixels(o,s,1,1,r.RGBA,r.UNSIGNED_BYTE,l);var h=ee(l,4),u=h[0],d=h[1],f=h[2],g=h[3];return[u,d,f,g]}function c(r,n,i){return(n=ae(n))in r?Object.defineProperty(r,n,{value:i,enumerable:!0,configurable:!0,writable:!0}):r[n]=i,r}function je(r,n){var i=Object.keys(r);if(Object.getOwnPropertySymbols){var e=Object.getOwnPropertySymbols(r);n&&(e=e.filter(function(t){return Object.getOwnPropertyDescriptor(r,t).enumerable})),i.push.apply(i,e)}return i}function b(r){for(var n=1;n<arguments.length;n++){var i=arguments[n]!=null?arguments[n]:{};n%2?je(Object(i),!0).forEach(function(e){c(r,e,i[e])}):Object.getOwnPropertyDescriptors?Object.defineProperties(r,Object.getOwnPropertyDescriptors(i)):je(Object(i)).forEach(function(e){Object.defineProperty(r,e,Object.getOwnPropertyDescriptor(i,e))})}return r}function ei(r,n){for(;!{}.hasOwnProperty.call(r,n)&&(r=Q(r))!==null;);return r}function Ae(){return Ae=typeof Reflect<"u"&&Reflect.get?Reflect.get.bind():function(r,n,i){var e=ei(r,n);if(e){var t=Object.getOwnPropertyDescriptor(e,n);return t.get?t.get.call(arguments.length<3?r:i):t.value}},Ae.apply(null,arguments)}function wt(r,n,i,e){var t=Ae(Q(r.prototype),n,i);return typeof t=="function"?function(a){return t.apply(i,a)}:t}function ti(r){return r.normalized?1:r.size}function ye(r){var n=0;return r.forEach(function(i){return n+=ti(i)}),n}function xt(r,n,i){var e=r==="VERTEX"?n.VERTEX_SHADER:n.FRAGMENT_SHADER,t=n.createShader(e);if(t===null)throw new Error("loadShader: error while creating the shader");n.shaderSource(t,i),n.compileShader(t);var a=n.getShaderParameter(t,n.COMPILE_STATUS);if(!a){var o=n.getShaderInfoLog(t);throw n.deleteShader(t),new Error(`loadShader: error while compiling the shader:
|
|
3
3
|
`.concat(o,`
|
|
4
4
|
`).concat(i))}return t}function ii(r,n){return xt("VERTEX",r,n)}function ri(r,n){return xt("FRAGMENT",r,n)}function ni(r,n){var i=r.createProgram();if(i===null)throw new Error("loadProgram: error while creating the program.");var e,t;for(e=0,t=n.length;e<t;e++)r.attachShader(i,n[e]);r.linkProgram(i);var a=r.getProgramParameter(i,r.LINK_STATUS);if(!a){var o=r.getProgramInfoLog(i);throw r.deleteProgram(i),new Error("loadProgram: error while linking the program: ".concat(o))}return i}function Ze(r){var n=r.gl,i=r.buffer,e=r.program,t=r.vertexShader,a=r.fragmentShader;n.deleteShader(t),n.deleteShader(a),n.deleteProgram(e),n.deleteBuffer(i)}var qe=`#define PICKING_MODE
|
package/assets/index.html
CHANGED
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
<link rel="icon" type="image/png" sizes="32x32" href="./favicon-32.png" />
|
|
13
13
|
<link rel="apple-touch-icon" href="./apple-touch-icon.png" />
|
|
14
14
|
<title>Canonry</title>
|
|
15
|
-
<script type="module" crossorigin src="./assets/index-
|
|
15
|
+
<script type="module" crossorigin src="./assets/index-rqOXhYwp.js"></script>
|
|
16
16
|
<link rel="modulepreload" crossorigin href="./assets/vendor-tanstack-Dock0eH1.js">
|
|
17
17
|
<link rel="modulepreload" crossorigin href="./assets/vendor-radix-4UOaVWza.js">
|
|
18
18
|
<link rel="modulepreload" crossorigin href="./assets/vendor-recharts-D8rt5lKn.js">
|
|
@@ -11189,6 +11189,15 @@ var ga4StatusDtoSchema = z34.object({
|
|
|
11189
11189
|
createdAt: z34.string().nullable().optional(),
|
|
11190
11190
|
updatedAt: z34.string().nullable().optional()
|
|
11191
11191
|
});
|
|
11192
|
+
var ga4PropertySummaryDtoSchema = z34.object({
|
|
11193
|
+
propertyId: z34.string(),
|
|
11194
|
+
displayName: z34.string(),
|
|
11195
|
+
/** GA4 account that owns the property. Two accounts can hold like-named properties. */
|
|
11196
|
+
accountName: z34.string()
|
|
11197
|
+
});
|
|
11198
|
+
var ga4PropertiesDtoSchema = z34.object({
|
|
11199
|
+
properties: z34.array(ga4PropertySummaryDtoSchema)
|
|
11200
|
+
});
|
|
11192
11201
|
var ga4SyncResponseDtoSchema = z34.object({
|
|
11193
11202
|
synced: z34.boolean(),
|
|
11194
11203
|
rowCount: z34.number().int().nonnegative(),
|
|
@@ -15393,6 +15402,7 @@ export {
|
|
|
15393
15402
|
aiReferralClassCounts,
|
|
15394
15403
|
formatAiReferralClassSummary,
|
|
15395
15404
|
ga4StatusDtoSchema,
|
|
15405
|
+
ga4PropertiesDtoSchema,
|
|
15396
15406
|
ga4SyncResponseDtoSchema,
|
|
15397
15407
|
ga4AiReferralHistoryEntrySchema,
|
|
15398
15408
|
ga4AiReferralDailyDtoSchema,
|
|
@@ -10,7 +10,7 @@ import {
|
|
|
10
10
|
loadConfig,
|
|
11
11
|
loadConfigRaw,
|
|
12
12
|
saveConfigPatch
|
|
13
|
-
} from "./chunk-
|
|
13
|
+
} from "./chunk-QDOZEMDK.js";
|
|
14
14
|
import {
|
|
15
15
|
CC_CACHE_DIR,
|
|
16
16
|
DUCKDB_SPEC,
|
|
@@ -139,7 +139,7 @@ import {
|
|
|
139
139
|
siteCrawlSnapshots,
|
|
140
140
|
toAlertView,
|
|
141
141
|
usageCounters
|
|
142
|
-
} from "./chunk-
|
|
142
|
+
} from "./chunk-QKLNTSQ2.js";
|
|
143
143
|
import {
|
|
144
144
|
AGENT_MEMORY_VALUE_MAX_BYTES,
|
|
145
145
|
AGENT_PROVIDER_IDS,
|
|
@@ -253,7 +253,7 @@ import {
|
|
|
253
253
|
validationError,
|
|
254
254
|
winnabilityClassLabel,
|
|
255
255
|
withRetry
|
|
256
|
-
} from "./chunk-
|
|
256
|
+
} from "./chunk-BU6C2DKF.js";
|
|
257
257
|
|
|
258
258
|
// src/telemetry.ts
|
|
259
259
|
import crypto from "crypto";
|
|
@@ -9084,7 +9084,7 @@ function readStoredGroundingSources(rawResponse) {
|
|
|
9084
9084
|
return result;
|
|
9085
9085
|
}
|
|
9086
9086
|
async function backfillInsightsCommand(project, opts) {
|
|
9087
|
-
const { IntelligenceService: IntelligenceService2 } = await import("./intelligence-service-
|
|
9087
|
+
const { IntelligenceService: IntelligenceService2 } = await import("./intelligence-service-RDGUEEZQ.js");
|
|
9088
9088
|
const config = loadConfig();
|
|
9089
9089
|
const db = createClient(config.database);
|
|
9090
9090
|
migrate(db);
|
|
@@ -81,7 +81,7 @@ import {
|
|
|
81
81
|
trafficConnectWordpressRequestSchema,
|
|
82
82
|
trafficEventKindSchema,
|
|
83
83
|
trafficSeriesGranularitySchema
|
|
84
|
-
} from "./chunk-
|
|
84
|
+
} from "./chunk-BU6C2DKF.js";
|
|
85
85
|
|
|
86
86
|
// src/config.ts
|
|
87
87
|
import fs from "fs";
|
|
@@ -4148,6 +4148,18 @@ var getApiV1ProjectsByNameGaStatus = (options) => {
|
|
|
4148
4148
|
...options
|
|
4149
4149
|
});
|
|
4150
4150
|
};
|
|
4151
|
+
var getApiV1ProjectsByNameGaProperties = (options) => {
|
|
4152
|
+
return (options.client ?? client).get({
|
|
4153
|
+
security: [
|
|
4154
|
+
{
|
|
4155
|
+
scheme: "bearer",
|
|
4156
|
+
type: "http"
|
|
4157
|
+
}
|
|
4158
|
+
],
|
|
4159
|
+
url: "/api/v1/projects/{name}/ga/properties",
|
|
4160
|
+
...options
|
|
4161
|
+
});
|
|
4162
|
+
};
|
|
4151
4163
|
var getApiV1ProjectsByNameGaMeasurementAnalysis = (options) => {
|
|
4152
4164
|
return (options.client ?? client).get({
|
|
4153
4165
|
security: [
|
|
@@ -6925,6 +6937,11 @@ var ApiClient = class {
|
|
|
6925
6937
|
() => getApiV1ProjectsByNameGaStatus({ client: this.heyClient, path: { name: project } })
|
|
6926
6938
|
);
|
|
6927
6939
|
}
|
|
6940
|
+
async gaProperties(project) {
|
|
6941
|
+
return this.invoke(
|
|
6942
|
+
() => getApiV1ProjectsByNameGaProperties({ client: this.heyClient, path: { name: project } })
|
|
6943
|
+
);
|
|
6944
|
+
}
|
|
6928
6945
|
async gaMeasurementAnalysis(project, params) {
|
|
6929
6946
|
return this.invoke(
|
|
6930
6947
|
() => getApiV1ProjectsByNameGaMeasurementAnalysis({
|
|
@@ -9299,6 +9316,17 @@ var canonryMcpTools = [
|
|
|
9299
9316
|
openApiOperations: ["GET /api/v1/projects/{name}/ga/status"],
|
|
9300
9317
|
handler: (client2, input) => client2.gaStatus(input.project)
|
|
9301
9318
|
}),
|
|
9319
|
+
defineTool({
|
|
9320
|
+
name: "canonry_ga_properties",
|
|
9321
|
+
title: "List GA4 properties",
|
|
9322
|
+
description: `List the GA4 properties the project's connected Google account can read, with their numeric property ids. Use this to find the id that "canonry ga connect --property-id" needs; it cannot be derived from the domain or the OAuth grant.`,
|
|
9323
|
+
access: "read",
|
|
9324
|
+
tier: "ga",
|
|
9325
|
+
inputSchema: projectInputSchema,
|
|
9326
|
+
annotations: readAnnotations(),
|
|
9327
|
+
openApiOperations: ["GET /api/v1/projects/{name}/ga/properties"],
|
|
9328
|
+
handler: (client2, input) => client2.gaProperties(input.project)
|
|
9329
|
+
}),
|
|
9302
9330
|
defineTool({
|
|
9303
9331
|
name: "canonry_ga_measurement_analysis",
|
|
9304
9332
|
title: "Analyze GA acquisition and search demand",
|
|
@@ -271,6 +271,7 @@ import {
|
|
|
271
271
|
formatWindowCountDelta,
|
|
272
272
|
ga4AiReferralDailyDtoSchema,
|
|
273
273
|
ga4AiReferralHistoryEntrySchema,
|
|
274
|
+
ga4PropertiesDtoSchema,
|
|
274
275
|
ga4SessionHistoryEntrySchema,
|
|
275
276
|
ga4SocialReferralHistoryEntrySchema,
|
|
276
277
|
ga4StatusDtoSchema,
|
|
@@ -581,7 +582,7 @@ import {
|
|
|
581
582
|
wordpressSchemaDeployResultDtoSchema,
|
|
582
583
|
wordpressSchemaStatusResultDtoSchema,
|
|
583
584
|
wordpressStatusDtoSchema
|
|
584
|
-
} from "./chunk-
|
|
585
|
+
} from "./chunk-BU6C2DKF.js";
|
|
585
586
|
|
|
586
587
|
// src/intelligence-service.ts
|
|
587
588
|
import { eq as eq59, desc as desc26, asc as asc11, and as and47, ne as ne7, or as or13, inArray as inArray21, gte as gte14, lte as lte12 } from "drizzle-orm";
|
|
@@ -9225,6 +9226,13 @@ function assertProjectScope(request, projectId) {
|
|
|
9225
9226
|
throw forbidden("This API key is scoped to a different project.");
|
|
9226
9227
|
}
|
|
9227
9228
|
}
|
|
9229
|
+
function assertNotProjectScoped(request, what) {
|
|
9230
|
+
if (request.apiKey?.projectId) {
|
|
9231
|
+
throw forbidden(
|
|
9232
|
+
`This API key is scoped to a single project, and ${what} covers every account the connected Google principal can see. Use a full-instance key.`
|
|
9233
|
+
);
|
|
9234
|
+
}
|
|
9235
|
+
}
|
|
9228
9236
|
function hashApiKey(key) {
|
|
9229
9237
|
return crypto4.createHash("sha256").update(key).digest("hex");
|
|
9230
9238
|
}
|
|
@@ -28064,6 +28072,7 @@ var SCHEMA_TABLE = {
|
|
|
28064
28072
|
GA4MeasurementAnalysisDto: gaMeasurementAnalysisDtoSchema,
|
|
28065
28073
|
GA4SessionHistoryEntry: ga4SessionHistoryEntrySchema,
|
|
28066
28074
|
GA4SocialReferralHistoryEntry: ga4SocialReferralHistoryEntrySchema,
|
|
28075
|
+
GA4PropertiesDto: ga4PropertiesDtoSchema,
|
|
28067
28076
|
GA4StatusDto: ga4StatusDtoSchema,
|
|
28068
28077
|
GA4SyncResponseDto: ga4SyncResponseDtoSchema,
|
|
28069
28078
|
GbpAccountListResponse: gbpAccountListResponseSchema,
|
|
@@ -32893,7 +32902,7 @@ var routeCatalog = [
|
|
|
32893
32902
|
{
|
|
32894
32903
|
method: "post",
|
|
32895
32904
|
path: "/api/v1/projects/{name}/ga/connect",
|
|
32896
|
-
summary: "Connect Google Analytics 4
|
|
32905
|
+
summary: "Connect Google Analytics 4 (service account or existing OAuth connection)",
|
|
32897
32906
|
tags: ["ga4"],
|
|
32898
32907
|
parameters: [nameParameter],
|
|
32899
32908
|
requestBody: {
|
|
@@ -32902,9 +32911,12 @@ var routeCatalog = [
|
|
|
32902
32911
|
"application/json": {
|
|
32903
32912
|
schema: {
|
|
32904
32913
|
type: "object",
|
|
32905
|
-
required: ["propertyId"
|
|
32914
|
+
required: ["propertyId"],
|
|
32906
32915
|
properties: {
|
|
32907
32916
|
propertyId: stringSchema,
|
|
32917
|
+
// Optional: omit it to select a property on an existing OAuth
|
|
32918
|
+
// connection (canonry google connect --type ga4). Required only
|
|
32919
|
+
// for service-account auth.
|
|
32908
32920
|
keyJson: stringSchema
|
|
32909
32921
|
}
|
|
32910
32922
|
}
|
|
@@ -32940,6 +32952,19 @@ var routeCatalog = [
|
|
|
32940
32952
|
404: errorResponse("Project not found.")
|
|
32941
32953
|
}
|
|
32942
32954
|
},
|
|
32955
|
+
{
|
|
32956
|
+
method: "get",
|
|
32957
|
+
path: "/api/v1/projects/{name}/ga/properties",
|
|
32958
|
+
summary: "List GA4 properties the connected account can read",
|
|
32959
|
+
description: "Lists every GA4 property visible to the project's OAuth connection, so the numeric property id needed by ga/connect can be discovered without leaving canonry. Requires an OAuth GA4 connection; service-account connections already carry their property id.",
|
|
32960
|
+
tags: ["ga4"],
|
|
32961
|
+
parameters: [nameParameter],
|
|
32962
|
+
responses: {
|
|
32963
|
+
200: jsonResponse("GA4 properties returned.", "GA4PropertiesDto"),
|
|
32964
|
+
400: errorResponse("No OAuth GA4 connection for this project."),
|
|
32965
|
+
404: errorResponse("Project not found.")
|
|
32966
|
+
}
|
|
32967
|
+
},
|
|
32943
32968
|
{
|
|
32944
32969
|
method: "get",
|
|
32945
32970
|
path: "/api/v1/projects/{name}/ga/measurement-analysis",
|
|
@@ -36114,6 +36139,7 @@ import crypto26 from "crypto";
|
|
|
36114
36139
|
|
|
36115
36140
|
// ../integration-google-analytics/src/constants.ts
|
|
36116
36141
|
var GA4_DATA_API_BASE = "https://analyticsdata.googleapis.com/v1beta";
|
|
36142
|
+
var GA4_ADMIN_API_BASE = "https://analyticsadmin.googleapis.com/v1beta";
|
|
36117
36143
|
var GA4_SCOPE = "https://www.googleapis.com/auth/analytics.readonly";
|
|
36118
36144
|
var GOOGLE_TOKEN_URL2 = "https://oauth2.googleapis.com/token";
|
|
36119
36145
|
var GA4_DEFAULT_SYNC_DAYS = 30;
|
|
@@ -36305,6 +36331,9 @@ function isRetryableGa4Error(err) {
|
|
|
36305
36331
|
if (err instanceof GA4ApiError) {
|
|
36306
36332
|
return err.status === 429 || err.status >= 500;
|
|
36307
36333
|
}
|
|
36334
|
+
if (err instanceof Error && (err.name === "TimeoutError" || err.name === "AbortError")) {
|
|
36335
|
+
return true;
|
|
36336
|
+
}
|
|
36308
36337
|
return false;
|
|
36309
36338
|
}
|
|
36310
36339
|
async function withGa4Retry(fn, errLabel) {
|
|
@@ -36678,6 +36707,69 @@ async function verifyConnectionWithToken(accessToken, propertyId) {
|
|
|
36678
36707
|
});
|
|
36679
36708
|
return true;
|
|
36680
36709
|
}
|
|
36710
|
+
async function listProperties(accessToken) {
|
|
36711
|
+
validateAccessToken2(accessToken);
|
|
36712
|
+
const properties = [];
|
|
36713
|
+
let pageToken;
|
|
36714
|
+
do {
|
|
36715
|
+
const url = new URL(`${GA4_ADMIN_API_BASE}/accountSummaries`);
|
|
36716
|
+
url.searchParams.set("pageSize", "200");
|
|
36717
|
+
if (pageToken) url.searchParams.set("pageToken", pageToken);
|
|
36718
|
+
const body = await withGa4Limit(() => withGa4Retry(async () => {
|
|
36719
|
+
const res = await fetch(url, {
|
|
36720
|
+
headers: { "Authorization": `Bearer ${accessToken}` },
|
|
36721
|
+
signal: AbortSignal.timeout(GA4_REQUEST_TIMEOUT_MS)
|
|
36722
|
+
});
|
|
36723
|
+
if (!res.ok) {
|
|
36724
|
+
const raw = await res.text().catch(() => "");
|
|
36725
|
+
let detail = "";
|
|
36726
|
+
let quotaReason = false;
|
|
36727
|
+
try {
|
|
36728
|
+
const parsed = JSON.parse(raw);
|
|
36729
|
+
if (parsed.error?.status === "SERVICE_DISABLED") {
|
|
36730
|
+
detail = " The Google Analytics Admin API is not enabled for this GCP project. Enable it at: https://console.developers.google.com/apis/api/analyticsadmin.googleapis.com/overview";
|
|
36731
|
+
} else if (parsed.error?.message) {
|
|
36732
|
+
detail = ` ${parsed.error.message}`;
|
|
36733
|
+
}
|
|
36734
|
+
quotaReason = (parsed.error?.errors ?? []).some(
|
|
36735
|
+
(e) => e.reason === "rateLimitExceeded" || e.reason === "quotaExceeded" || e.reason === "userRateLimitExceeded"
|
|
36736
|
+
) || parsed.error?.status === "RESOURCE_EXHAUSTED";
|
|
36737
|
+
} catch {
|
|
36738
|
+
if (raw.length < 200) detail = ` ${raw}`;
|
|
36739
|
+
}
|
|
36740
|
+
const sanitized = detail.replace(new RegExp(escapeRegExp3(accessToken), "g"), "***");
|
|
36741
|
+
const retryAfterSeconds = res.status === 429 || res.status >= 500 || res.status === 403 && quotaReason ? parseRetryAfter(res.headers.get("retry-after")) : void 0;
|
|
36742
|
+
ga4Log("error", "admin.account-summaries-failed", {
|
|
36743
|
+
httpStatus: res.status,
|
|
36744
|
+
retryAfterSeconds,
|
|
36745
|
+
quotaReason
|
|
36746
|
+
});
|
|
36747
|
+
throw new GA4ApiError(
|
|
36748
|
+
`Failed to list GA4 properties.${sanitized}`,
|
|
36749
|
+
// A quota 403 is surfaced as 429 so every downstream consumer — the
|
|
36750
|
+
// retry predicate and the route's error mapper — reads it as rate
|
|
36751
|
+
// limiting rather than as a permission denial.
|
|
36752
|
+
res.status === 403 && quotaReason ? 429 : res.status,
|
|
36753
|
+
retryAfterSeconds
|
|
36754
|
+
);
|
|
36755
|
+
}
|
|
36756
|
+
return await res.json();
|
|
36757
|
+
}, "GA4 accountSummaries"));
|
|
36758
|
+
for (const account of body.accountSummaries ?? []) {
|
|
36759
|
+
for (const summary of account.propertySummaries ?? []) {
|
|
36760
|
+
const propertyId = (summary.property ?? "").split("/").pop() ?? "";
|
|
36761
|
+
if (!propertyId) continue;
|
|
36762
|
+
properties.push({
|
|
36763
|
+
propertyId,
|
|
36764
|
+
displayName: summary.displayName ?? "",
|
|
36765
|
+
accountName: account.displayName ?? ""
|
|
36766
|
+
});
|
|
36767
|
+
}
|
|
36768
|
+
}
|
|
36769
|
+
pageToken = body.nextPageToken;
|
|
36770
|
+
} while (pageToken);
|
|
36771
|
+
return properties;
|
|
36772
|
+
}
|
|
36681
36773
|
async function fetchAggregateSummary(accessToken, propertyId, days) {
|
|
36682
36774
|
validateAccessToken2(accessToken);
|
|
36683
36775
|
validatePropertyId(propertyId);
|
|
@@ -37742,6 +37834,7 @@ async function googleRoutes(app, opts) {
|
|
|
37742
37834
|
return reply.status(204).send();
|
|
37743
37835
|
});
|
|
37744
37836
|
app.get("/projects/:name/google/properties", async (request) => {
|
|
37837
|
+
assertNotProjectScoped(request, "listing Search Console properties");
|
|
37745
37838
|
const { clientId: googleClientId, clientSecret: googleClientSecret } = getAuthConfig();
|
|
37746
37839
|
if (!googleClientId || !googleClientSecret) {
|
|
37747
37840
|
throw validationError("Google OAuth is not configured");
|
|
@@ -38658,6 +38751,7 @@ async function googleRoutes(app, opts) {
|
|
|
38658
38751
|
return listSelectionResponse(project.id);
|
|
38659
38752
|
});
|
|
38660
38753
|
app.get("/projects/:name/gbp/accounts", async (request) => {
|
|
38754
|
+
assertNotProjectScoped(request, "listing Business Profile accounts");
|
|
38661
38755
|
const { clientId: googleClientId, clientSecret: googleClientSecret } = getAuthConfig();
|
|
38662
38756
|
if (!googleClientId || !googleClientSecret) {
|
|
38663
38757
|
throw validationError("Google OAuth is not configured");
|
|
@@ -44178,6 +44272,7 @@ async function bingRoutes(app, opts) {
|
|
|
44178
44272
|
};
|
|
44179
44273
|
});
|
|
44180
44274
|
app.get("/projects/:name/bing/sites", async (request) => {
|
|
44275
|
+
assertNotProjectScoped(request, "listing Bing Webmaster sites");
|
|
44181
44276
|
const store = requireConnectionStore();
|
|
44182
44277
|
const project = resolveProject(app.db, request.params.name);
|
|
44183
44278
|
const conn = requireConnection(store, project.canonicalDomain);
|
|
@@ -45044,6 +45139,22 @@ async function refreshOAuthTokenIfNeeded(googleStore, authConfig, canonicalDomai
|
|
|
45044
45139
|
}
|
|
45045
45140
|
return oauthConn.accessToken;
|
|
45046
45141
|
}
|
|
45142
|
+
function ga4ErrorToAppError(err, context) {
|
|
45143
|
+
if (err instanceof AppError) return err;
|
|
45144
|
+
if (err instanceof GA4ApiError) {
|
|
45145
|
+
if (err.status === 429) {
|
|
45146
|
+
return quotaExceeded("Google Analytics Admin API (rate limited; retries exhausted)");
|
|
45147
|
+
}
|
|
45148
|
+
if (err.status === 401 || err.status === 403) {
|
|
45149
|
+
return forbidden(
|
|
45150
|
+
`${context}: the connected Google account was rejected by Google (${err.status}). Reconnect with "canonry google connect <project> --type ga4".`,
|
|
45151
|
+
{ reason: "ga4-upstream-auth", upstreamStatus: err.status }
|
|
45152
|
+
);
|
|
45153
|
+
}
|
|
45154
|
+
return providerError(`${context}: ${err.message}`);
|
|
45155
|
+
}
|
|
45156
|
+
return providerError(`${context}: ${err instanceof Error ? err.message : String(err)}`);
|
|
45157
|
+
}
|
|
45047
45158
|
async function resolveGa4AccessToken(opts, projectName, canonicalDomain) {
|
|
45048
45159
|
const saConn = opts.ga4CredentialStore?.getConnection(projectName);
|
|
45049
45160
|
if (saConn?.clientEmail && saConn?.privateKey && saConn?.propertyId) {
|
|
@@ -45065,7 +45176,7 @@ async function resolveGa4AccessToken(opts, projectName, canonicalDomain) {
|
|
|
45065
45176
|
}
|
|
45066
45177
|
if (!oauthConn.propertyId) {
|
|
45067
45178
|
throw validationError(
|
|
45068
|
-
'GA4 property ID not set. Run "canonry ga
|
|
45179
|
+
'GA4 property ID not set. Run "canonry ga properties <project>" to list the readable properties, then "canonry ga connect <project> --property-id <id>" to select one.'
|
|
45069
45180
|
);
|
|
45070
45181
|
}
|
|
45071
45182
|
const accessToken = await refreshOAuthTokenIfNeeded(googleStore, authConfig, canonicalDomain, {
|
|
@@ -45194,6 +45305,33 @@ async function ga4Routes(app, opts) {
|
|
|
45194
45305
|
});
|
|
45195
45306
|
return reply.status(204).send();
|
|
45196
45307
|
});
|
|
45308
|
+
app.get("/projects/:name/ga/properties", async (request) => {
|
|
45309
|
+
assertNotProjectScoped(request, "listing GA4 properties");
|
|
45310
|
+
const project = resolveProject(app.db, request.params.name);
|
|
45311
|
+
const googleStore = opts.googleConnectionStore;
|
|
45312
|
+
const authConfig = opts.getGoogleAuthConfig?.();
|
|
45313
|
+
if (!googleStore || !authConfig) {
|
|
45314
|
+
throw validationError(
|
|
45315
|
+
'Google OAuth is not configured. Run "canonry google connect <project> --type ga4" first.'
|
|
45316
|
+
);
|
|
45317
|
+
}
|
|
45318
|
+
const oauthConn = googleStore.getConnection(project.canonicalDomain, "ga4");
|
|
45319
|
+
if (!oauthConn?.accessToken || !oauthConn?.refreshToken) {
|
|
45320
|
+
throw validationError(
|
|
45321
|
+
'No GA4 OAuth connection for this project. Run "canonry google connect <project> --type ga4" first. Service-account connections already carry their property id and do not need this listing.'
|
|
45322
|
+
);
|
|
45323
|
+
}
|
|
45324
|
+
try {
|
|
45325
|
+
const accessToken = await refreshOAuthTokenIfNeeded(googleStore, authConfig, project.canonicalDomain, {
|
|
45326
|
+
accessToken: oauthConn.accessToken,
|
|
45327
|
+
refreshToken: oauthConn.refreshToken,
|
|
45328
|
+
tokenExpiresAt: oauthConn.tokenExpiresAt
|
|
45329
|
+
});
|
|
45330
|
+
return { properties: await listProperties(accessToken) };
|
|
45331
|
+
} catch (err) {
|
|
45332
|
+
throw ga4ErrorToAppError(err, "Failed to list GA4 properties");
|
|
45333
|
+
}
|
|
45334
|
+
});
|
|
45197
45335
|
app.get("/projects/:name/ga/status", async (request, _reply) => {
|
|
45198
45336
|
const project = resolveProject(app.db, request.params.name);
|
|
45199
45337
|
const saConn = opts.ga4CredentialStore?.getConnection(project.name);
|
package/dist/cli.js
CHANGED
|
@@ -31,7 +31,7 @@ import {
|
|
|
31
31
|
showFirstRunNotice,
|
|
32
32
|
trackCliCommandFinished,
|
|
33
33
|
trackEvent
|
|
34
|
-
} from "./chunk-
|
|
34
|
+
} from "./chunk-L5SMSDZB.js";
|
|
35
35
|
import {
|
|
36
36
|
CliError,
|
|
37
37
|
EXIT_SYSTEM_ERROR,
|
|
@@ -51,7 +51,7 @@ import {
|
|
|
51
51
|
saveConfigPatch,
|
|
52
52
|
systemError,
|
|
53
53
|
usageError
|
|
54
|
-
} from "./chunk-
|
|
54
|
+
} from "./chunk-QDOZEMDK.js";
|
|
55
55
|
import {
|
|
56
56
|
CLOUDFLARE_WORKER_BINDINGS,
|
|
57
57
|
CLOUDFLARE_WORKER_GENERATED_MARKER,
|
|
@@ -65,7 +65,7 @@ import {
|
|
|
65
65
|
projects,
|
|
66
66
|
queries,
|
|
67
67
|
renderReportHtml
|
|
68
|
-
} from "./chunk-
|
|
68
|
+
} from "./chunk-QKLNTSQ2.js";
|
|
69
69
|
import {
|
|
70
70
|
AdsDeliverySnapshotStatuses,
|
|
71
71
|
AdsHistoricalCampaignRollupStatuses,
|
|
@@ -129,7 +129,7 @@ import {
|
|
|
129
129
|
providerQuotaPolicySchema,
|
|
130
130
|
resolveProviderInput,
|
|
131
131
|
winnabilityClassSchema
|
|
132
|
-
} from "./chunk-
|
|
132
|
+
} from "./chunk-BU6C2DKF.js";
|
|
133
133
|
|
|
134
134
|
// src/cli.ts
|
|
135
135
|
import { pathToFileURL } from "url";
|
|
@@ -3941,6 +3941,31 @@ async function gaStatus(project, format) {
|
|
|
3941
3941
|
console.log(` Last Synced: ${result.lastSyncedAt ?? "(never)"}`);
|
|
3942
3942
|
console.log(` Connected: ${result.createdAt ?? "unknown"}`);
|
|
3943
3943
|
}
|
|
3944
|
+
async function gaProperties(project, format) {
|
|
3945
|
+
const client = getClient7();
|
|
3946
|
+
const result = await client.gaProperties(project);
|
|
3947
|
+
if (format === "jsonl") {
|
|
3948
|
+
emitJsonl(result.properties.map((p) => ({ project, ...p })));
|
|
3949
|
+
return;
|
|
3950
|
+
}
|
|
3951
|
+
if (isMachineFormat(format)) {
|
|
3952
|
+
console.log(JSON.stringify(result, null, 2));
|
|
3953
|
+
return;
|
|
3954
|
+
}
|
|
3955
|
+
if (result.properties.length === 0) {
|
|
3956
|
+
console.log(`No GA4 properties visible to the connected account for "${project}".`);
|
|
3957
|
+
return;
|
|
3958
|
+
}
|
|
3959
|
+
console.log("Available GA4 properties:\n");
|
|
3960
|
+
const idWidth = Math.max(11, ...result.properties.map((p) => p.propertyId.length));
|
|
3961
|
+
const nameWidth = Math.max(12, ...result.properties.map((p) => p.displayName.length));
|
|
3962
|
+
console.log(` ${"PROPERTY ID".padEnd(idWidth)} ${"DISPLAY NAME".padEnd(nameWidth)} ACCOUNT`);
|
|
3963
|
+
console.log(` ${"\u2500".repeat(idWidth)} ${"\u2500".repeat(nameWidth)} ${"\u2500".repeat(12)}`);
|
|
3964
|
+
for (const p of result.properties) {
|
|
3965
|
+
console.log(` ${p.propertyId.padEnd(idWidth)} ${p.displayName.padEnd(nameWidth)} ${p.accountName}`);
|
|
3966
|
+
}
|
|
3967
|
+
console.log('\nUse "canonry ga connect <project> --property-id <id>" to select one.');
|
|
3968
|
+
}
|
|
3944
3969
|
async function gaSync(project, opts) {
|
|
3945
3970
|
const client = getClient7();
|
|
3946
3971
|
const body = {};
|
|
@@ -4506,14 +4531,14 @@ function rangeValues(values) {
|
|
|
4506
4531
|
var GA_CLI_COMMANDS = [
|
|
4507
4532
|
{
|
|
4508
4533
|
path: ["ga", "connect"],
|
|
4509
|
-
usage: "canonry ga connect <project> --property-id <id> --key-file <path> [--key-json <json>] [--format json]",
|
|
4534
|
+
usage: "canonry ga connect <project> --property-id <id> [--key-file <path>] [--key-json <json>] [--format json]",
|
|
4510
4535
|
options: {
|
|
4511
4536
|
"property-id": stringOption(),
|
|
4512
4537
|
"key-file": stringOption(),
|
|
4513
4538
|
"key-json": stringOption()
|
|
4514
4539
|
},
|
|
4515
4540
|
run: async (input) => {
|
|
4516
|
-
const project = requireProject(input, "ga.connect", "canonry ga connect <project> --property-id <id> --key-file <path>");
|
|
4541
|
+
const project = requireProject(input, "ga.connect", "canonry ga connect <project> --property-id <id> [--key-file <path>]");
|
|
4517
4542
|
const propertyId = getString(input.values, "property-id");
|
|
4518
4543
|
if (!propertyId) {
|
|
4519
4544
|
throw new Error("--property-id is required");
|
|
@@ -4534,6 +4559,14 @@ var GA_CLI_COMMANDS = [
|
|
|
4534
4559
|
await gaDisconnect(project, input.format);
|
|
4535
4560
|
}
|
|
4536
4561
|
},
|
|
4562
|
+
{
|
|
4563
|
+
path: ["ga", "properties"],
|
|
4564
|
+
usage: "canonry ga properties <project> [--format json]",
|
|
4565
|
+
run: async (input) => {
|
|
4566
|
+
const project = requireProject(input, "ga.properties", "canonry ga properties <project> [--format json]");
|
|
4567
|
+
await gaProperties(project, input.format);
|
|
4568
|
+
}
|
|
4569
|
+
},
|
|
4537
4570
|
{
|
|
4538
4571
|
path: ["ga", "status"],
|
|
4539
4572
|
usage: "canonry ga status <project> [--format json]",
|
|
@@ -4691,7 +4724,7 @@ var GA_CLI_COMMANDS = [
|
|
|
4691
4724
|
unknownSubcommand(input.positionals[0], {
|
|
4692
4725
|
command: "ga",
|
|
4693
4726
|
usage: "canonry ga <subcommand> <project> [args]",
|
|
4694
|
-
available: ["connect", "disconnect", "status", "sync", "measurement-analysis", "traffic", "coverage", "ai-referral-history", "ai-referral-daily", "social-referral-history", "session-history", "social-referral-summary", "attribution"]
|
|
4727
|
+
available: ["connect", "disconnect", "status", "properties", "sync", "measurement-analysis", "traffic", "coverage", "ai-referral-history", "ai-referral-daily", "social-referral-history", "session-history", "social-referral-summary", "attribution"]
|
|
4695
4728
|
});
|
|
4696
4729
|
}
|
|
4697
4730
|
}
|
package/dist/index.js
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import {
|
|
2
2
|
createServer
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-L5SMSDZB.js";
|
|
4
4
|
import {
|
|
5
5
|
loadConfig
|
|
6
|
-
} from "./chunk-
|
|
7
|
-
import "./chunk-
|
|
8
|
-
import "./chunk-
|
|
6
|
+
} from "./chunk-QDOZEMDK.js";
|
|
7
|
+
import "./chunk-QKLNTSQ2.js";
|
|
8
|
+
import "./chunk-BU6C2DKF.js";
|
|
9
9
|
export {
|
|
10
10
|
createServer,
|
|
11
11
|
loadConfig
|
package/dist/mcp.js
CHANGED
|
@@ -3,10 +3,10 @@ import {
|
|
|
3
3
|
PACKAGE_VERSION,
|
|
4
4
|
canonryMcpTools,
|
|
5
5
|
createApiClient
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-QDOZEMDK.js";
|
|
7
7
|
import {
|
|
8
8
|
isReadOnlyKey
|
|
9
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-BU6C2DKF.js";
|
|
10
10
|
|
|
11
11
|
// src/mcp/cli.ts
|
|
12
12
|
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@canonry/canonry",
|
|
3
|
-
"version": "4.
|
|
3
|
+
"version": "4.165.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Agent-first open-source AEO operating platform - track how answer engines cite your domain",
|
|
6
6
|
"license": "FSL-1.1-ALv2",
|
|
@@ -70,29 +70,29 @@
|
|
|
70
70
|
"@types/node-cron": "^3.0.11",
|
|
71
71
|
"tsup": "^8.5.1",
|
|
72
72
|
"tsx": "^4.19.0",
|
|
73
|
-
"@ainyc/canonry-api-client": "0.0.0",
|
|
74
73
|
"@ainyc/canonry-api-routes": "0.0.0",
|
|
74
|
+
"@ainyc/canonry-api-client": "0.0.0",
|
|
75
75
|
"@ainyc/canonry-config": "0.0.0",
|
|
76
76
|
"@ainyc/canonry-contracts": "0.0.0",
|
|
77
77
|
"@ainyc/canonry-db": "0.0.0",
|
|
78
78
|
"@ainyc/canonry-integration-bing": "0.0.0",
|
|
79
79
|
"@ainyc/canonry-integration-cloudflare-queue": "0.0.0",
|
|
80
80
|
"@ainyc/canonry-integration-openai-ads": "0.0.0",
|
|
81
|
-
"@ainyc/canonry-integration-cloud-run": "0.0.0",
|
|
82
81
|
"@ainyc/canonry-integration-commoncrawl": "0.0.0",
|
|
82
|
+
"@ainyc/canonry-integration-cloud-run": "0.0.0",
|
|
83
83
|
"@ainyc/canonry-integration-cloudflare-worker": "0.0.0",
|
|
84
84
|
"@ainyc/canonry-integration-google": "0.0.0",
|
|
85
|
-
"@ainyc/canonry-integration-google-business-profile": "0.0.0",
|
|
86
85
|
"@ainyc/canonry-integration-google-places": "0.0.0",
|
|
86
|
+
"@ainyc/canonry-integration-google-business-profile": "0.0.0",
|
|
87
87
|
"@ainyc/canonry-integration-wordpress": "0.0.0",
|
|
88
88
|
"@ainyc/canonry-integration-traffic": "0.0.0",
|
|
89
89
|
"@ainyc/canonry-intelligence": "0.0.0",
|
|
90
|
-
"@ainyc/canonry-provider-cdp": "0.0.0",
|
|
91
|
-
"@ainyc/canonry-provider-local": "0.0.0",
|
|
92
90
|
"@ainyc/canonry-provider-claude": "0.0.0",
|
|
93
|
-
"@ainyc/canonry-provider-
|
|
91
|
+
"@ainyc/canonry-provider-local": "0.0.0",
|
|
92
|
+
"@ainyc/canonry-provider-gemini": "0.0.0",
|
|
93
|
+
"@ainyc/canonry-provider-cdp": "0.0.0",
|
|
94
94
|
"@ainyc/canonry-provider-openai": "0.0.0",
|
|
95
|
-
"@ainyc/canonry-provider-
|
|
95
|
+
"@ainyc/canonry-provider-perplexity": "0.0.0"
|
|
96
96
|
},
|
|
97
97
|
"scripts": {
|
|
98
98
|
"build": "tsx scripts/copy-agent-assets.ts && tsup && tsx build-web.ts",
|