@canonry/canonry 7.15.0 → 7.17.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 +22 -6
- package/assets/assets/{AuditHistoryPanel-Cl9tUvSZ.js → AuditHistoryPanel-CUde9U_6.js} +1 -1
- package/assets/assets/{BacklinksPage-CTeTJ9dh.js → BacklinksPage-DMQPw8ks.js} +1 -1
- package/assets/assets/{HistoryPage-DpOoXr2P.js → HistoryPage-DZSa1gYf.js} +1 -1
- package/assets/assets/{MeasurementPropertyPage-DxXsgM25.js → MeasurementPropertyPage-DgW17Jpd.js} +1 -1
- package/assets/assets/ProjectPage-C8vdtqtA.js +8 -0
- package/assets/assets/{RunsPage-CfDi7I1z.js → RunsPage-DRfNd-Jp.js} +1 -1
- package/assets/assets/{SettingsPage-BHDb1apK.js → SettingsPage-D38Gl1Nv.js} +1 -1
- package/assets/assets/{SiteHealthSection-DQZyy4P_.js → SiteHealthSection-CR3zB84D.js} +3 -3
- package/assets/assets/{TrafficPage-DX_vN2RL.js → TrafficPage-DX3qRPgQ.js} +2 -2
- package/assets/assets/{TrafficSourceDetailPage-Cg92zrtZ.js → TrafficSourceDetailPage-CigB82vX.js} +1 -1
- package/assets/assets/{extract-error-message-BKxVCbov.js → extract-error-message-DsMnnkxT.js} +1 -1
- package/assets/assets/{index-DoQJETc6.js → index-DBr6ISbx.js} +25 -25
- package/assets/assets/{react-sigma_core.esm.min-BhqZcSgh.js → react-sigma_core.esm.min-CkYxzGpi.js} +1 -1
- package/assets/assets/{v2-overview-adapter-DZ5YsE_G.js → v2-overview-adapter-5x8UiA07.js} +1 -1
- package/assets/index.html +1 -1
- package/dist/{chunk-YFCKHEKM.js → chunk-2MBI5SYB.js} +3 -3
- package/dist/{chunk-7HJYGDRW.js → chunk-3NAZXITW.js} +1680 -840
- package/dist/{chunk-KOBK4I5N.js → chunk-PVWGKDY6.js} +156 -2
- package/dist/{chunk-SG6T3DEP.js → chunk-QPOXDS43.js} +2 -2
- package/dist/{chunk-LC7GMHOL.js → chunk-RBQUGZM4.js} +23 -1
- package/dist/{chunk-N2MRW2DH.js → chunk-WEKVQK3O.js} +43 -20
- package/dist/{chunk-SGQBPTWQ.js → chunk-WVBLFG7H.js} +30 -3
- package/dist/cli.js +123 -12
- package/dist/{demo-server-YWGUGZMI.js → demo-server-BVJFYR4V.js} +68 -15
- package/dist/index.js +6 -6
- package/dist/{intelligence-service-7RKUUR7O.js → intelligence-service-FK2W72X7.js} +2 -2
- package/dist/mcp.js +4 -4
- package/package.json +9 -9
- package/assets/assets/ProjectPage-By9arjLJ.js +0 -8
|
@@ -5679,6 +5679,60 @@ function describeError(err) {
|
|
|
5679
5679
|
return "unknown error";
|
|
5680
5680
|
}
|
|
5681
5681
|
}
|
|
5682
|
+
var NETWORK_ERROR_CODE = /^[A-Z][A-Z0-9_]{1,63}$/;
|
|
5683
|
+
var MAX_CAUSE_DEPTH = 5;
|
|
5684
|
+
var RESOLVE_CODES = /* @__PURE__ */ new Set(["ENOTFOUND", "EAI_AGAIN", "ENODATA"]);
|
|
5685
|
+
var CONNECT_CODES = /* @__PURE__ */ new Set(["ECONNREFUSED", "UND_ERR_CONNECT_TIMEOUT", "ETIMEDOUT", "EHOSTUNREACH", "ENETUNREACH"]);
|
|
5686
|
+
function stringField(value) {
|
|
5687
|
+
return typeof value === "string" && value !== "" ? value : null;
|
|
5688
|
+
}
|
|
5689
|
+
function findNetworkCause(err) {
|
|
5690
|
+
let node = err;
|
|
5691
|
+
for (let depth = 0; depth < MAX_CAUSE_DEPTH && node !== null && typeof node === "object"; depth++) {
|
|
5692
|
+
const record = node;
|
|
5693
|
+
if (typeof record.code === "string" && NETWORK_ERROR_CODE.test(record.code)) {
|
|
5694
|
+
return {
|
|
5695
|
+
code: record.code,
|
|
5696
|
+
syscall: stringField(record.syscall),
|
|
5697
|
+
hostname: stringField(record.hostname),
|
|
5698
|
+
address: stringField(record.address),
|
|
5699
|
+
port: typeof record.port === "number" && Number.isInteger(record.port) ? record.port : null
|
|
5700
|
+
};
|
|
5701
|
+
}
|
|
5702
|
+
node = record.cause ?? (Array.isArray(record.errors) ? record.errors[0] : void 0);
|
|
5703
|
+
}
|
|
5704
|
+
return null;
|
|
5705
|
+
}
|
|
5706
|
+
function requestHostname(requestUrl) {
|
|
5707
|
+
if (requestUrl === void 0) return null;
|
|
5708
|
+
try {
|
|
5709
|
+
return stringField(new URL(requestUrl).hostname);
|
|
5710
|
+
} catch {
|
|
5711
|
+
return null;
|
|
5712
|
+
}
|
|
5713
|
+
}
|
|
5714
|
+
function describeFetchError(err, requestUrl) {
|
|
5715
|
+
const message = describeError(err);
|
|
5716
|
+
let cause;
|
|
5717
|
+
try {
|
|
5718
|
+
cause = findNetworkCause(err);
|
|
5719
|
+
} catch {
|
|
5720
|
+
return message;
|
|
5721
|
+
}
|
|
5722
|
+
if (!cause) return message;
|
|
5723
|
+
const host = cause.hostname ?? requestHostname(requestUrl);
|
|
5724
|
+
const resolving = cause.syscall === "getaddrinfo" || RESOLVE_CODES.has(cause.code);
|
|
5725
|
+
const connecting = cause.syscall === "connect" || CONNECT_CODES.has(cause.code);
|
|
5726
|
+
const verb = resolving ? "resolving" : connecting ? "connecting to" : "calling";
|
|
5727
|
+
const address = cause.address && cause.address !== host ? `${cause.address.includes(":") ? `[${cause.address}]` : cause.address}${cause.port !== null ? `:${cause.port}` : ""}` : null;
|
|
5728
|
+
const parts = [cause.code, host ? `${verb} ${host}` : null, address ? `at ${address}` : null];
|
|
5729
|
+
return `${message} (${parts.filter((part) => part !== null).join(" ")})`;
|
|
5730
|
+
}
|
|
5731
|
+
function isFetchTransportError(err) {
|
|
5732
|
+
if (!(err instanceof Error)) return false;
|
|
5733
|
+
if (err.name === "TimeoutError" || err.name === "AbortError") return true;
|
|
5734
|
+
return err instanceof TypeError && err.message === "fetch failed";
|
|
5735
|
+
}
|
|
5682
5736
|
|
|
5683
5737
|
// ../contracts/src/measurement.ts
|
|
5684
5738
|
import { z as z12 } from "zod";
|
|
@@ -6127,6 +6181,7 @@ var gbpSyncResponseSchema = z13.object({
|
|
|
6127
6181
|
runId: z13.string(),
|
|
6128
6182
|
status: z13.string()
|
|
6129
6183
|
});
|
|
6184
|
+
var GBP_NO_SELECTED_LOCATIONS_ERROR = "No selected GBP locations to sync. Discover and select locations first.";
|
|
6130
6185
|
var gbpDailyMetricDtoSchema = z13.object({
|
|
6131
6186
|
locationName: z13.string(),
|
|
6132
6187
|
date: z13.string(),
|
|
@@ -17361,6 +17416,84 @@ var ga4PropertySummaryDtoSchema = z51.object({
|
|
|
17361
17416
|
var ga4PropertiesDtoSchema = z51.object({
|
|
17362
17417
|
properties: z51.array(ga4PropertySummaryDtoSchema)
|
|
17363
17418
|
});
|
|
17419
|
+
var gaSearchLandingWindowSchema = z51.enum(["7d", "28d", "90d"]);
|
|
17420
|
+
var GA_SEARCH_LANDING_WINDOWS = gaSearchLandingWindowSchema.options;
|
|
17421
|
+
var GA_SEARCH_LANDING_WINDOW_DAYS = {
|
|
17422
|
+
"7d": 7,
|
|
17423
|
+
"28d": 28,
|
|
17424
|
+
"90d": 90
|
|
17425
|
+
};
|
|
17426
|
+
var GA_SEARCH_LANDING_DEFAULT_WINDOW = "28d";
|
|
17427
|
+
var GA_SEARCH_LANDING_DEFAULT_LIMIT = 50;
|
|
17428
|
+
var GA_SEARCH_LANDING_MAX_LIMIT = 1e3;
|
|
17429
|
+
var gaSearchLandingStatusSchema = z51.enum(["never-synced", "ready", "unavailable", "error"]);
|
|
17430
|
+
var gaSearchLandingMetricsSchema = z51.object({
|
|
17431
|
+
organicGoogleSearchClicks: z51.number().int().nonnegative(),
|
|
17432
|
+
organicGoogleSearchImpressions: z51.number().int().nonnegative(),
|
|
17433
|
+
/** GA4's own click-through rate (0..1). Null when there were no impressions. */
|
|
17434
|
+
organicGoogleSearchClickThroughRate: fraction(z51.number().min(0).max(1)).nullable(),
|
|
17435
|
+
/** GA4's own average position. Null when there were no impressions. */
|
|
17436
|
+
organicGoogleSearchAveragePosition: z51.number().nonnegative().nullable(),
|
|
17437
|
+
/**
|
|
17438
|
+
* GA4's plain `activeUsers` from the same request, which is what GA4's own
|
|
17439
|
+
* report shows in this column (verified against the GA4 UI). Not limited to
|
|
17440
|
+
* Google organic sessions.
|
|
17441
|
+
*/
|
|
17442
|
+
activeUsers: z51.number().int().nonnegative()
|
|
17443
|
+
});
|
|
17444
|
+
var gaSearchLandingPageRowSchema = gaSearchLandingMetricsSchema.extend({
|
|
17445
|
+
/** GA4's `landingPagePlusQueryString`, exactly as reported (never normalized). */
|
|
17446
|
+
landingPage: z51.string()
|
|
17447
|
+
});
|
|
17448
|
+
var gaSearchLandingPagesResponseSchema = z51.object({
|
|
17449
|
+
source: z51.literal("ga4-search-console-link"),
|
|
17450
|
+
status: gaSearchLandingStatusSchema,
|
|
17451
|
+
/** The last failed attempt's message (Google's own text for `unavailable`). */
|
|
17452
|
+
error: z51.string().nullable(),
|
|
17453
|
+
/** When the stored snapshot was written. Null when none exists. */
|
|
17454
|
+
syncedAt: z51.string().datetime().nullable(),
|
|
17455
|
+
/** When a sync last tried to refresh the snapshot, successful or not. */
|
|
17456
|
+
attemptedAt: z51.string().datetime().nullable(),
|
|
17457
|
+
window: gaSearchLandingWindowSchema,
|
|
17458
|
+
/** Inclusive first day of the stored window, in the property's time zone. */
|
|
17459
|
+
windowStart: z51.iso.date().nullable(),
|
|
17460
|
+
/** Inclusive last day of the stored window (yesterday at sync time). */
|
|
17461
|
+
windowEnd: z51.iso.date().nullable(),
|
|
17462
|
+
windowDays: z51.number().int().positive().nullable(),
|
|
17463
|
+
/** GA4 property reporting time zone the window dates are in. */
|
|
17464
|
+
timeZone: z51.string().nullable(),
|
|
17465
|
+
subjectToThresholding: z51.boolean(),
|
|
17466
|
+
dataLossFromOtherRow: z51.boolean(),
|
|
17467
|
+
/** GA4's own TOTAL row for the window. Never a sum of `rows`. Null when no snapshot exists. */
|
|
17468
|
+
total: gaSearchLandingMetricsSchema.nullable(),
|
|
17469
|
+
/** Rows GA4 reported for the window. Can exceed `totalRows` when `rowsCapped`. */
|
|
17470
|
+
reportRowCount: z51.number().int().nonnegative().nullable(),
|
|
17471
|
+
/** True when GA4 reported more rows than were stored (the per-window row cap). */
|
|
17472
|
+
rowsCapped: z51.boolean(),
|
|
17473
|
+
/** Stored rows for the window, the population `limit` / `offset` page over. */
|
|
17474
|
+
totalRows: z51.number().int().nonnegative(),
|
|
17475
|
+
limit: z51.number().int().positive(),
|
|
17476
|
+
offset: z51.number().int().nonnegative(),
|
|
17477
|
+
/** Ordered by clicks, then impressions (both descending), then landing page. */
|
|
17478
|
+
rows: z51.array(gaSearchLandingPageRowSchema)
|
|
17479
|
+
});
|
|
17480
|
+
function gaSearchLandingHasSearchData(total) {
|
|
17481
|
+
return total.organicGoogleSearchClicks > 0 || total.organicGoogleSearchImpressions > 0;
|
|
17482
|
+
}
|
|
17483
|
+
var gaSearchLandingSyncResultSchema = z51.object({
|
|
17484
|
+
status: z51.enum(["ready", "unavailable", "error"]),
|
|
17485
|
+
/** Windows written by this sync, empty unless `ready`. */
|
|
17486
|
+
windows: z51.array(z51.object({
|
|
17487
|
+
window: gaSearchLandingWindowSchema,
|
|
17488
|
+
rowCount: z51.number().int().nonnegative(),
|
|
17489
|
+
reportRowCount: z51.number().int().nonnegative(),
|
|
17490
|
+
rowsCapped: z51.boolean()
|
|
17491
|
+
})),
|
|
17492
|
+
/** Landing-page rows written across every window. */
|
|
17493
|
+
rowCount: z51.number().int().nonnegative(),
|
|
17494
|
+
error: z51.string().optional()
|
|
17495
|
+
});
|
|
17496
|
+
var gaSyncOnlySchema = z51.enum(["traffic", "ai", "social", "search-landing"]);
|
|
17364
17497
|
var ga4SyncResponseDtoSchema = z51.object({
|
|
17365
17498
|
synced: z51.boolean(),
|
|
17366
17499
|
rowCount: z51.number().int().nonnegative(),
|
|
@@ -17383,12 +17516,21 @@ var ga4SyncResponseDtoSchema = z51.object({
|
|
|
17383
17516
|
syncedAt: z51.string(),
|
|
17384
17517
|
measurement: z51.object({
|
|
17385
17518
|
acquisition: z51.object({ days: z51.number().int().nonnegative(), status: z51.enum(["ready", "error"]), rowCount: z51.number().int().nonnegative(), error: z51.string().optional() }),
|
|
17386
|
-
leads: z51.object({ days: z51.number().int().nonnegative(), status: z51.enum(["ready", "error", "not-configured"]), rowCount: z51.number().int().nonnegative(), attributionScope: z51.enum(["landing-page", "channel"]).optional(), error: z51.string().optional() })
|
|
17519
|
+
leads: z51.object({ days: z51.number().int().nonnegative(), status: z51.enum(["ready", "error", "not-configured"]), rowCount: z51.number().int().nonnegative(), attributionScope: z51.enum(["landing-page", "channel"]).optional(), error: z51.string().optional() }),
|
|
17520
|
+
/**
|
|
17521
|
+
* GA4's Search Console landing-page snapshot. Absent when `only` names
|
|
17522
|
+
* another slice, since this sync did not attempt it. Its failure never
|
|
17523
|
+
* fails the sync: the previous snapshot is kept.
|
|
17524
|
+
*/
|
|
17525
|
+
searchLandingPages: gaSearchLandingSyncResultSchema.optional()
|
|
17387
17526
|
}),
|
|
17388
17527
|
/**
|
|
17389
17528
|
* Components that were written this run. Present when `only` is set.
|
|
17390
17529
|
* Always includes `traffic` and `summary` (the share denominator) plus
|
|
17391
|
-
* the requested
|
|
17530
|
+
* the requested slice: `ai`, `social` or `search-landing`. `search-landing`
|
|
17531
|
+
* fails soft, so it is listed only when its snapshot was stored; a failed
|
|
17532
|
+
* or `unavailable` attempt is left out and reported in
|
|
17533
|
+
* `measurement.searchLandingPages`.
|
|
17392
17534
|
*/
|
|
17393
17535
|
syncedComponents: z51.array(z51.string()).optional()
|
|
17394
17536
|
});
|
|
@@ -22401,6 +22543,8 @@ export {
|
|
|
22401
22543
|
internalError,
|
|
22402
22544
|
runtimeStateMissing,
|
|
22403
22545
|
describeError,
|
|
22546
|
+
describeFetchError,
|
|
22547
|
+
isFetchTransportError,
|
|
22404
22548
|
AI_ENGINE_DOMAINS,
|
|
22405
22549
|
AI_ENGINE_SELF_DOMAINS,
|
|
22406
22550
|
VERTEX_AI_SEARCH_PROXY_DOMAIN,
|
|
@@ -22452,6 +22596,7 @@ export {
|
|
|
22452
22596
|
gbpLocationSelectionRequestSchema,
|
|
22453
22597
|
gbpSyncRequestSchema,
|
|
22454
22598
|
gbpSyncResponseSchema,
|
|
22599
|
+
GBP_NO_SELECTED_LOCATIONS_ERROR,
|
|
22455
22600
|
gbpDailyMetricListResponseSchema,
|
|
22456
22601
|
gbpKeywordImpressionListResponseSchema,
|
|
22457
22602
|
gbpPlaceActionListResponseSchema,
|
|
@@ -23005,6 +23150,15 @@ export {
|
|
|
23005
23150
|
formatAiReferralClassSummary,
|
|
23006
23151
|
ga4StatusDtoSchema,
|
|
23007
23152
|
ga4PropertiesDtoSchema,
|
|
23153
|
+
gaSearchLandingWindowSchema,
|
|
23154
|
+
GA_SEARCH_LANDING_WINDOWS,
|
|
23155
|
+
GA_SEARCH_LANDING_WINDOW_DAYS,
|
|
23156
|
+
GA_SEARCH_LANDING_DEFAULT_WINDOW,
|
|
23157
|
+
GA_SEARCH_LANDING_DEFAULT_LIMIT,
|
|
23158
|
+
GA_SEARCH_LANDING_MAX_LIMIT,
|
|
23159
|
+
gaSearchLandingPagesResponseSchema,
|
|
23160
|
+
gaSearchLandingHasSearchData,
|
|
23161
|
+
gaSyncOnlySchema,
|
|
23008
23162
|
ga4SyncResponseDtoSchema,
|
|
23009
23163
|
GaMoverChangeBases,
|
|
23010
23164
|
gaSocialReferralTrendResponseSchema,
|
|
@@ -5,7 +5,7 @@ import {
|
|
|
5
5
|
siteCrawlGraphNodes,
|
|
6
6
|
siteCrawlPages,
|
|
7
7
|
siteCrawlSnapshots
|
|
8
|
-
} from "./chunk-
|
|
8
|
+
} from "./chunk-3NAZXITW.js";
|
|
9
9
|
import {
|
|
10
10
|
SITE_CRAWL_GRAPH_MAX_EDGES,
|
|
11
11
|
SITE_CRAWL_GRAPH_MAX_NODES,
|
|
@@ -14,7 +14,7 @@ import {
|
|
|
14
14
|
factorStatusFromDistribution,
|
|
15
15
|
factorStatusFromScore,
|
|
16
16
|
roundPreservingTotal
|
|
17
|
-
} from "./chunk-
|
|
17
|
+
} from "./chunk-PVWGKDY6.js";
|
|
18
18
|
|
|
19
19
|
// src/site-audit-factors.ts
|
|
20
20
|
function recordedSharePct(factor) {
|
|
@@ -3,6 +3,7 @@ import {
|
|
|
3
3
|
AGENT_MEMORY_VALUE_MAX_BYTES,
|
|
4
4
|
DISCOVERY_MAX_PROBES_CAP,
|
|
5
5
|
DISCOVERY_PROBE_CONCURRENCY_CAP,
|
|
6
|
+
GA_SEARCH_LANDING_MAX_LIMIT,
|
|
6
7
|
GOOGLE_MARKETING_STORED_SNAPSHOT_PAGE_MAX,
|
|
7
8
|
LATEST_RUN_ID,
|
|
8
9
|
PROVIDER_ACCOUNT_FAILURE_STREAK,
|
|
@@ -44,6 +45,7 @@ import {
|
|
|
44
45
|
feedbackSubmissionSchema,
|
|
45
46
|
gaMeasurementAnalysisWindowSchema,
|
|
46
47
|
gaMeasurementHostScopeSchema,
|
|
48
|
+
gaSearchLandingWindowSchema,
|
|
47
49
|
googleAdsMetricsWindowSchema,
|
|
48
50
|
gscPerformanceOrderBySchema,
|
|
49
51
|
keywordBatchRequestSchema,
|
|
@@ -139,7 +141,7 @@ import {
|
|
|
139
141
|
trafficSeriesGranularitySchema,
|
|
140
142
|
visibilityCompareSelectionSchema,
|
|
141
143
|
visibilityReportRequestSchema
|
|
142
|
-
} from "./chunk-
|
|
144
|
+
} from "./chunk-PVWGKDY6.js";
|
|
143
145
|
|
|
144
146
|
// src/cli-error.ts
|
|
145
147
|
function isMachineFormat(format) {
|
|
@@ -719,6 +721,12 @@ var gaMeasurementAnalysisInputSchema = z3.object({
|
|
|
719
721
|
pathPrefix: z3.string().min(1).optional(),
|
|
720
722
|
limit: z3.number().int().positive().max(100).optional()
|
|
721
723
|
});
|
|
724
|
+
var gaSearchLandingPagesInputSchema = z3.object({
|
|
725
|
+
project: projectNameSchema,
|
|
726
|
+
window: gaSearchLandingWindowSchema.optional(),
|
|
727
|
+
limit: z3.number().int().positive().max(GA_SEARCH_LANDING_MAX_LIMIT).optional(),
|
|
728
|
+
offset: z3.number().int().nonnegative().optional()
|
|
729
|
+
});
|
|
722
730
|
var queriesInputSchema = z3.object({
|
|
723
731
|
project: projectNameSchema,
|
|
724
732
|
request: queryBatchRequestSchema
|
|
@@ -2291,6 +2299,20 @@ var canonryMcpTools = [
|
|
|
2291
2299
|
compactStringParams(input, ["window", "hostScope", "pathPrefix", "limit"])
|
|
2292
2300
|
)
|
|
2293
2301
|
}),
|
|
2302
|
+
defineTool({
|
|
2303
|
+
name: "canonry_ga_search_landing_pages",
|
|
2304
|
+
title: "Get GA4 Google organic search landing pages",
|
|
2305
|
+
description: "Read GA4's \"Google organic search traffic: Landing page + query string\" report (Search Console link) as the last GA sync stored it: clicks, impressions, CTR, average position and active users per landing page for the 7, 28 (default) or 90 days ending yesterday in the property time zone. `total` is GA4's own Total row; never sum `rows`. Status `unavailable` means GA4 refused the Search Console metrics (link Search Console in GA4); the previous snapshot is still returned. Stored data only.",
|
|
2306
|
+
access: "read",
|
|
2307
|
+
tier: "ga",
|
|
2308
|
+
inputSchema: gaSearchLandingPagesInputSchema,
|
|
2309
|
+
annotations: readAnnotations(),
|
|
2310
|
+
openApiOperations: ["GET /api/v1/projects/{name}/ga/search-landing-pages"],
|
|
2311
|
+
handler: (client, input) => client.gaSearchLandingPages(
|
|
2312
|
+
input.project,
|
|
2313
|
+
compactStringParams(input, ["window", "limit", "offset"])
|
|
2314
|
+
)
|
|
2315
|
+
}),
|
|
2294
2316
|
defineTool({
|
|
2295
2317
|
name: "canonry_ga_traffic",
|
|
2296
2318
|
title: "Get GA traffic",
|
|
@@ -20,20 +20,20 @@ import {
|
|
|
20
20
|
saveConfig,
|
|
21
21
|
saveConfigPatch,
|
|
22
22
|
sentimentInstallReadiness
|
|
23
|
-
} from "./chunk-
|
|
23
|
+
} from "./chunk-WVBLFG7H.js";
|
|
24
24
|
import {
|
|
25
25
|
computeFactorAverages,
|
|
26
26
|
deleteSiteCrawlGraphLayout,
|
|
27
27
|
persistSiteCrawlGraphLayout,
|
|
28
28
|
prepareSiteCrawlGraphLayout,
|
|
29
29
|
recordedSharePct
|
|
30
|
-
} from "./chunk-
|
|
30
|
+
} from "./chunk-QPOXDS43.js";
|
|
31
31
|
import {
|
|
32
32
|
CanonryMcpToolNames,
|
|
33
33
|
CliError,
|
|
34
34
|
PACKAGE_VERSION,
|
|
35
35
|
canonryMcpTools
|
|
36
|
-
} from "./chunk-
|
|
36
|
+
} from "./chunk-RBQUGZM4.js";
|
|
37
37
|
import {
|
|
38
38
|
CC_CACHE_DIR,
|
|
39
39
|
DUCKDB_SPEC,
|
|
@@ -217,7 +217,7 @@ import {
|
|
|
217
217
|
siteLivenessState,
|
|
218
218
|
toAlertView,
|
|
219
219
|
usageCounters
|
|
220
|
-
} from "./chunk-
|
|
220
|
+
} from "./chunk-3NAZXITW.js";
|
|
221
221
|
import {
|
|
222
222
|
AGENT_MEMORY_VALUE_MAX_BYTES,
|
|
223
223
|
AGENT_NONE,
|
|
@@ -238,6 +238,7 @@ import {
|
|
|
238
238
|
DEFAULT_VIEWER_RESEARCH_DAILY_RUN_LIMIT,
|
|
239
239
|
DiscoveryCompetitorTypes,
|
|
240
240
|
FEEDBACK_LIMITS,
|
|
241
|
+
GBP_NO_SELECTED_LOCATIONS_ERROR,
|
|
241
242
|
GOOGLE_ADS_CAMPAIGN_METRICS_MAX_CAMPAIGNS,
|
|
242
243
|
GOOGLE_ADS_CAMPAIGN_METRICS_MAX_DAYS,
|
|
243
244
|
GOOGLE_ADS_CAMPAIGN_METRICS_MAX_ROWS,
|
|
@@ -328,6 +329,7 @@ import {
|
|
|
328
329
|
deriveSiteHealthState,
|
|
329
330
|
describeBatchIneligibility,
|
|
330
331
|
describeError,
|
|
332
|
+
describeFetchError,
|
|
331
333
|
detectAgentRuntime,
|
|
332
334
|
determineAnswerMentioned,
|
|
333
335
|
dollarsToMicros,
|
|
@@ -430,7 +432,7 @@ import {
|
|
|
430
432
|
winnabilityClassLabel,
|
|
431
433
|
withRetry,
|
|
432
434
|
withSkippedProviders
|
|
433
|
-
} from "./chunk-
|
|
435
|
+
} from "./chunk-PVWGKDY6.js";
|
|
434
436
|
|
|
435
437
|
// src/runtime-context.ts
|
|
436
438
|
function cliRuntimeContext(env = process.env, stdio = process) {
|
|
@@ -1597,15 +1599,16 @@ var GoogleAdsClient = class {
|
|
|
1597
1599
|
if (includeLoginCustomerId && this.#loginCustomerId) {
|
|
1598
1600
|
headers["login-customer-id"] = this.#loginCustomerId;
|
|
1599
1601
|
}
|
|
1602
|
+
const url = `${GOOGLE_ADS_API_BASE}${path9}`;
|
|
1600
1603
|
let response;
|
|
1601
1604
|
try {
|
|
1602
|
-
response = await this.#fetch(
|
|
1605
|
+
response = await this.#fetch(url, {
|
|
1603
1606
|
...init,
|
|
1604
1607
|
headers,
|
|
1605
1608
|
signal: AbortSignal.timeout(this.#requestTimeoutMs)
|
|
1606
1609
|
});
|
|
1607
1610
|
} catch (error) {
|
|
1608
|
-
const detail =
|
|
1611
|
+
const detail = describeFetchError(error, url);
|
|
1609
1612
|
throw new GoogleAdsApiError(
|
|
1610
1613
|
`Google Ads API request failed: ${sanitizeText(detail, this.#secrets())}`
|
|
1611
1614
|
);
|
|
@@ -8042,7 +8045,7 @@ function nonBlank(value) {
|
|
|
8042
8045
|
return trimmed ? trimmed : void 0;
|
|
8043
8046
|
}
|
|
8044
8047
|
function resolveBuildCommit(env = process.env) {
|
|
8045
|
-
const embedded = true ? "
|
|
8048
|
+
const embedded = true ? "292663bc656bcd51a4a32fa879fbdcd7f7935398" : void 0;
|
|
8046
8049
|
return nonBlank(embedded) ?? nonBlank(env.CANONRY_COMMIT);
|
|
8047
8050
|
}
|
|
8048
8051
|
function resolveInstanceIdentity(env = process.env) {
|
|
@@ -11005,7 +11008,7 @@ async function executeGbpSync(db, runId, projectId, opts) {
|
|
|
11005
11008
|
locationRows = locationRows.filter((l) => wanted.has(l.locationName));
|
|
11006
11009
|
}
|
|
11007
11010
|
if (locationRows.length === 0) {
|
|
11008
|
-
throw new Error(
|
|
11011
|
+
throw new Error(GBP_NO_SELECTED_LOCATIONS_ERROR);
|
|
11009
11012
|
}
|
|
11010
11013
|
locationRows = await refreshSelectedLocationProfiles(db, projectId, accessToken, locationRows);
|
|
11011
11014
|
const daysOfMetrics = opts.daysOfMetrics ?? DEFAULT_DAYS_OF_METRICS;
|
|
@@ -15453,27 +15456,47 @@ function gaRefreshDays(now = /* @__PURE__ */ new Date()) {
|
|
|
15453
15456
|
const reach = inclusiveDayCount(`${reportMonth}-01`, now.toISOString().slice(0, 10)) ?? 0;
|
|
15454
15457
|
return Math.max(30, reach);
|
|
15455
15458
|
}
|
|
15459
|
+
function queuedRun(result2) {
|
|
15460
|
+
const record2 = asRecord(result2);
|
|
15461
|
+
const runId = record2?.runId ?? record2?.id;
|
|
15462
|
+
const runStatus = record2?.status;
|
|
15463
|
+
return {
|
|
15464
|
+
runId: typeof runId === "string" ? runId : null,
|
|
15465
|
+
runStatus: typeof runStatus === "string" ? runStatus : null
|
|
15466
|
+
};
|
|
15467
|
+
}
|
|
15456
15468
|
async function refreshAllIntegrations(client, projectName, now = /* @__PURE__ */ new Date()) {
|
|
15457
15469
|
const integrations = [
|
|
15458
|
-
{ name: "gsc", run: () => client.gscSync(projectName, {}) },
|
|
15459
|
-
{ name: "bing", run: () => client.bingInspectSitemap(projectName, {}) },
|
|
15460
|
-
{ name: "ga", run: () => client.gaSync(projectName, { days: gaRefreshDays(now) }) },
|
|
15461
|
-
{ name: "gbp", run: () => client.triggerGbpSync(projectName, {}) },
|
|
15470
|
+
{ name: "gsc", completion: "queued", run: () => client.gscSync(projectName, {}) },
|
|
15471
|
+
{ name: "bing", completion: "queued", run: () => client.bingInspectSitemap(projectName, {}) },
|
|
15472
|
+
{ name: "ga", completion: "synchronous", run: () => client.gaSync(projectName, { days: gaRefreshDays(now) }) },
|
|
15473
|
+
{ name: "gbp", completion: "queued", run: () => client.triggerGbpSync(projectName, {}) },
|
|
15462
15474
|
// `ads` remains the OpenAI / ChatGPT Ads integration. For scheduled
|
|
15463
15475
|
// refreshes, Google providers have explicit names and fan out only here.
|
|
15464
|
-
{ name: "ads", run: () => client.triggerAdsSync(projectName) },
|
|
15465
|
-
{ name: "google-ads", run: () => client.triggerGoogleAdsSync(projectName) },
|
|
15466
|
-
{ name: "gtm", run: () => client.triggerGtmSync(projectName) }
|
|
15476
|
+
{ name: "ads", completion: "queued", run: () => client.triggerAdsSync(projectName) },
|
|
15477
|
+
{ name: "google-ads", completion: "queued", run: () => client.triggerGoogleAdsSync(projectName) },
|
|
15478
|
+
{ name: "gtm", completion: "queued", run: () => client.triggerGtmSync(projectName) }
|
|
15467
15479
|
];
|
|
15468
15480
|
const results = await Promise.allSettled(integrations.map((i) => i.run()));
|
|
15469
15481
|
results.forEach((result2, idx) => {
|
|
15470
|
-
const integration = integrations[idx]
|
|
15471
|
-
if (result2.status === "
|
|
15472
|
-
log19.info("integration.refreshed", { projectName, integration });
|
|
15473
|
-
} else {
|
|
15482
|
+
const { name: integration, completion } = integrations[idx];
|
|
15483
|
+
if (result2.status === "rejected") {
|
|
15474
15484
|
const reason = result2.reason;
|
|
15475
15485
|
const message = describeError(reason);
|
|
15476
15486
|
log19.warn("integration.refresh-failed", { projectName, integration, error: message });
|
|
15487
|
+
return;
|
|
15488
|
+
}
|
|
15489
|
+
switch (completion) {
|
|
15490
|
+
case "synchronous":
|
|
15491
|
+
log19.info("integration.refreshed", { projectName, integration });
|
|
15492
|
+
return;
|
|
15493
|
+
case "queued":
|
|
15494
|
+
log19.info("integration.queued", { projectName, integration, ...queuedRun(result2.value) });
|
|
15495
|
+
return;
|
|
15496
|
+
default: {
|
|
15497
|
+
const _exhaustive = completion;
|
|
15498
|
+
return _exhaustive;
|
|
15499
|
+
}
|
|
15477
15500
|
}
|
|
15478
15501
|
});
|
|
15479
15502
|
}
|
|
@@ -5,7 +5,7 @@ import {
|
|
|
5
5
|
PACKAGE_VERSION,
|
|
6
6
|
canonryMcpTools,
|
|
7
7
|
isMachineFormat
|
|
8
|
-
} from "./chunk-
|
|
8
|
+
} from "./chunk-RBQUGZM4.js";
|
|
9
9
|
import {
|
|
10
10
|
AGENT_PROVIDER_IDS,
|
|
11
11
|
CANONRY_NPM_PACKAGE_URL,
|
|
@@ -50,7 +50,7 @@ import {
|
|
|
50
50
|
skillsClientSchema,
|
|
51
51
|
upgradeCaveatFor,
|
|
52
52
|
upgradeCommandFor
|
|
53
|
-
} from "./chunk-
|
|
53
|
+
} from "./chunk-PVWGKDY6.js";
|
|
54
54
|
|
|
55
55
|
// src/config.ts
|
|
56
56
|
import fs from "fs";
|
|
@@ -5212,6 +5212,18 @@ var getApiV1ProjectsByNameGaMeasurementAnalysis = (options) => {
|
|
|
5212
5212
|
...options
|
|
5213
5213
|
});
|
|
5214
5214
|
};
|
|
5215
|
+
var getApiV1ProjectsByNameGaSearchLandingPages = (options) => {
|
|
5216
|
+
return (options.client ?? client).get({
|
|
5217
|
+
security: [
|
|
5218
|
+
{
|
|
5219
|
+
scheme: "bearer",
|
|
5220
|
+
type: "http"
|
|
5221
|
+
}
|
|
5222
|
+
],
|
|
5223
|
+
url: "/api/v1/projects/{name}/ga/search-landing-pages",
|
|
5224
|
+
...options
|
|
5225
|
+
});
|
|
5226
|
+
};
|
|
5215
5227
|
var postApiV1ProjectsByNameGaSync = (options) => {
|
|
5216
5228
|
return (options.client ?? client).post({
|
|
5217
5229
|
security: [
|
|
@@ -8598,11 +8610,26 @@ var ApiClient = class {
|
|
|
8598
8610
|
})
|
|
8599
8611
|
);
|
|
8600
8612
|
}
|
|
8613
|
+
/**
|
|
8614
|
+
* One stored window of GA4's Search Console landing-page report
|
|
8615
|
+
* (`window`, `limit`, `offset`). Its `total` is GA4's own Total row.
|
|
8616
|
+
*/
|
|
8617
|
+
async gaSearchLandingPages(project, params) {
|
|
8618
|
+
return this.invoke(
|
|
8619
|
+
() => getApiV1ProjectsByNameGaSearchLandingPages({
|
|
8620
|
+
client: this.heyClient,
|
|
8621
|
+
path: { name: project },
|
|
8622
|
+
query: params
|
|
8623
|
+
})
|
|
8624
|
+
);
|
|
8625
|
+
}
|
|
8601
8626
|
async gaSync(project, body) {
|
|
8602
8627
|
return this.invoke(
|
|
8603
8628
|
() => postApiV1ProjectsByNameGaSync({
|
|
8604
8629
|
client: this.heyClient,
|
|
8605
8630
|
path: { name: project },
|
|
8631
|
+
// `--only` is forwarded verbatim: the server validates it against
|
|
8632
|
+
// `gaSyncOnlySchema` and names the accepted values in its 400.
|
|
8606
8633
|
body: body ?? {}
|
|
8607
8634
|
})
|
|
8608
8635
|
);
|
|
@@ -9694,7 +9721,7 @@ var CANONRY_MCP_TOOLKITS = [
|
|
|
9694
9721
|
{
|
|
9695
9722
|
name: "ga",
|
|
9696
9723
|
title: "Google Analytics 4",
|
|
9697
|
-
description: "Read GA traffic, AI/social referral history, attribution trend, and
|
|
9724
|
+
description: "Read GA traffic, AI/social referral history, attribution trend, session history, and GA4's Search Console landing-page report (Google organic clicks, impressions, CTR, position and active users per landing page).",
|
|
9698
9725
|
whenToLoad: "Load when you need traffic, referral, or attribution data from Google Analytics 4."
|
|
9699
9726
|
},
|
|
9700
9727
|
{
|