@ainyc/canonry 4.78.0 → 4.81.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 +38 -12
- package/assets/assets/{BacklinksPage-CwXveumn.js → BacklinksPage-DHShKKpo.js} +1 -1
- package/assets/assets/{ChartPrimitives-DntKGI5J.js → ChartPrimitives-udHScxjY.js} +1 -1
- package/assets/assets/ProjectPage-BsS1anh7.js +6 -0
- package/assets/assets/{RunRow-DMtYXaxG.js → RunRow-CXyPHMVQ.js} +1 -1
- package/assets/assets/{RunsPage-Cz-YlucO.js → RunsPage-BpQ_NpFt.js} +1 -1
- package/assets/assets/{SettingsPage-BCuG3C-0.js → SettingsPage-1ep4ch7n.js} +1 -1
- package/assets/assets/{TrafficPage-DV8X47wa.js → TrafficPage-C3Hx-sE7.js} +1 -1
- package/assets/assets/TrafficSourceDetailPage-B26n2R6G.js +1 -0
- package/assets/assets/{arrow-left-CUmHyNnF.js → arrow-left-Dc_IPJxw.js} +1 -1
- package/assets/assets/{extract-error-message-DFjy9_zi.js → extract-error-message-B3PoKkHW.js} +1 -1
- package/assets/assets/{index-D9smxU6R.js → index-DhdFTQkU.js} +86 -86
- package/assets/assets/{trash-2-B_UtEEm8.js → trash-2-BQ69cGl0.js} +1 -1
- package/assets/index.html +1 -1
- package/dist/{chunk-XI6YSTGE.js → chunk-6XOZSS3Y.js} +258 -8
- package/dist/{chunk-KPN22EWK.js → chunk-GMT3YPLT.js} +214 -4
- package/dist/{chunk-3WXARKUE.js → chunk-UAQ42NVJ.js} +1346 -357
- package/dist/{chunk-QKTIP6GC.js → chunk-VX5C7DK7.js} +902 -313
- package/dist/cli.js +468 -152
- package/dist/index.d.ts +17 -0
- package/dist/index.js +4 -4
- package/dist/{intelligence-service-CDVUUG7O.js → intelligence-service-CAAQAKPN.js} +2 -2
- package/dist/mcp.js +9 -3
- package/package.json +9 -8
- package/assets/assets/ProjectPage-CVudiU8X.js +0 -6
- package/assets/assets/TrafficSourceDetailPage-BmYhK9jm.js +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
import{c}from"./index-
|
|
1
|
+
import{c}from"./index-DhdFTQkU.js";const a=[["circle",{cx:"12",cy:"12",r:"10",key:"1mglay"}],["path",{d:"m9 12 2 2 4-4",key:"dzmm74"}]],h=c("circle-check",a);const e=[["circle",{cx:"12",cy:"12",r:"10",key:"1mglay"}],["path",{d:"M9.09 9a3 3 0 0 1 5.83 1c0 2-3 3-3 3",key:"1u773s"}],["path",{d:"M12 17h.01",key:"p32p05"}]],n=c("circle-question-mark",e);const o=[["path",{d:"M12 15V3",key:"m9g1x1"}],["path",{d:"M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4",key:"ih7n3h"}],["path",{d:"m7 10 5 5 5-5",key:"brsn70"}]],s=c("download",o);const t=[["path",{d:"M10 11v6",key:"nco0om"}],["path",{d:"M14 11v6",key:"outv1u"}],["path",{d:"M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6",key:"miytrc"}],["path",{d:"M3 6h18",key:"d0wm0j"}],["path",{d:"M8 6V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2",key:"e791ji"}]],r=c("trash-2",t);export{h as C,s as D,r as T,n as a};
|
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-DhdFTQkU.js"></script>
|
|
16
16
|
<link rel="modulepreload" crossorigin href="./assets/vendor-tanstack-Dq7p98wZ.js">
|
|
17
17
|
<link rel="modulepreload" crossorigin href="./assets/vendor-radix-B57xfQbP.js">
|
|
18
18
|
<link rel="modulepreload" crossorigin href="./assets/vendor-recharts-ClRVR6aX.js">
|
|
@@ -2,6 +2,7 @@ import {
|
|
|
2
2
|
AGENT_MEMORY_KEY_MAX_LENGTH,
|
|
3
3
|
AGENT_MEMORY_VALUE_MAX_BYTES,
|
|
4
4
|
DISCOVERY_MAX_PROBES_CAP,
|
|
5
|
+
backlinkSourceSchema,
|
|
5
6
|
competitorBatchRequestSchema,
|
|
6
7
|
discoveryBucketSchema,
|
|
7
8
|
discoveryCompetitorTypeSchema,
|
|
@@ -22,7 +23,7 @@ import {
|
|
|
22
23
|
trafficConnectVercelRequestSchema,
|
|
23
24
|
trafficConnectWordpressRequestSchema,
|
|
24
25
|
trafficEventKindSchema
|
|
25
|
-
} from "./chunk-
|
|
26
|
+
} from "./chunk-GMT3YPLT.js";
|
|
26
27
|
|
|
27
28
|
// src/config.ts
|
|
28
29
|
import fs from "fs";
|
|
@@ -2193,6 +2194,94 @@ var getApiV1ProjectsByNameGbpSummary = (options) => {
|
|
|
2193
2194
|
...options
|
|
2194
2195
|
});
|
|
2195
2196
|
};
|
|
2197
|
+
var postApiV1ProjectsByNameAdsConnect = (options) => {
|
|
2198
|
+
return (options.client ?? client).post({
|
|
2199
|
+
security: [
|
|
2200
|
+
{
|
|
2201
|
+
scheme: "bearer",
|
|
2202
|
+
type: "http"
|
|
2203
|
+
}
|
|
2204
|
+
],
|
|
2205
|
+
url: "/api/v1/projects/{name}/ads/connect",
|
|
2206
|
+
...options,
|
|
2207
|
+
headers: {
|
|
2208
|
+
"Content-Type": "application/json",
|
|
2209
|
+
...options.headers
|
|
2210
|
+
}
|
|
2211
|
+
});
|
|
2212
|
+
};
|
|
2213
|
+
var deleteApiV1ProjectsByNameAdsConnection = (options) => {
|
|
2214
|
+
return (options.client ?? client).delete({
|
|
2215
|
+
security: [
|
|
2216
|
+
{
|
|
2217
|
+
scheme: "bearer",
|
|
2218
|
+
type: "http"
|
|
2219
|
+
}
|
|
2220
|
+
],
|
|
2221
|
+
url: "/api/v1/projects/{name}/ads/connection",
|
|
2222
|
+
...options
|
|
2223
|
+
});
|
|
2224
|
+
};
|
|
2225
|
+
var getApiV1ProjectsByNameAdsStatus = (options) => {
|
|
2226
|
+
return (options.client ?? client).get({
|
|
2227
|
+
security: [
|
|
2228
|
+
{
|
|
2229
|
+
scheme: "bearer",
|
|
2230
|
+
type: "http"
|
|
2231
|
+
}
|
|
2232
|
+
],
|
|
2233
|
+
url: "/api/v1/projects/{name}/ads/status",
|
|
2234
|
+
...options
|
|
2235
|
+
});
|
|
2236
|
+
};
|
|
2237
|
+
var postApiV1ProjectsByNameAdsSync = (options) => {
|
|
2238
|
+
return (options.client ?? client).post({
|
|
2239
|
+
security: [
|
|
2240
|
+
{
|
|
2241
|
+
scheme: "bearer",
|
|
2242
|
+
type: "http"
|
|
2243
|
+
}
|
|
2244
|
+
],
|
|
2245
|
+
url: "/api/v1/projects/{name}/ads/sync",
|
|
2246
|
+
...options
|
|
2247
|
+
});
|
|
2248
|
+
};
|
|
2249
|
+
var getApiV1ProjectsByNameAdsCampaigns = (options) => {
|
|
2250
|
+
return (options.client ?? client).get({
|
|
2251
|
+
security: [
|
|
2252
|
+
{
|
|
2253
|
+
scheme: "bearer",
|
|
2254
|
+
type: "http"
|
|
2255
|
+
}
|
|
2256
|
+
],
|
|
2257
|
+
url: "/api/v1/projects/{name}/ads/campaigns",
|
|
2258
|
+
...options
|
|
2259
|
+
});
|
|
2260
|
+
};
|
|
2261
|
+
var getApiV1ProjectsByNameAdsInsights = (options) => {
|
|
2262
|
+
return (options.client ?? client).get({
|
|
2263
|
+
security: [
|
|
2264
|
+
{
|
|
2265
|
+
scheme: "bearer",
|
|
2266
|
+
type: "http"
|
|
2267
|
+
}
|
|
2268
|
+
],
|
|
2269
|
+
url: "/api/v1/projects/{name}/ads/insights",
|
|
2270
|
+
...options
|
|
2271
|
+
});
|
|
2272
|
+
};
|
|
2273
|
+
var getApiV1ProjectsByNameAdsSummary = (options) => {
|
|
2274
|
+
return (options.client ?? client).get({
|
|
2275
|
+
security: [
|
|
2276
|
+
{
|
|
2277
|
+
scheme: "bearer",
|
|
2278
|
+
type: "http"
|
|
2279
|
+
}
|
|
2280
|
+
],
|
|
2281
|
+
url: "/api/v1/projects/{name}/ads/summary",
|
|
2282
|
+
...options
|
|
2283
|
+
});
|
|
2284
|
+
};
|
|
2196
2285
|
var postApiV1ProjectsByNameBingConnect = (options) => {
|
|
2197
2286
|
return (options.client ?? client).post({
|
|
2198
2287
|
security: [
|
|
@@ -3133,6 +3222,30 @@ var getApiV1ProjectsByNameBacklinksHistory = (options) => {
|
|
|
3133
3222
|
...options
|
|
3134
3223
|
});
|
|
3135
3224
|
};
|
|
3225
|
+
var getApiV1ProjectsByNameBacklinksSources = (options) => {
|
|
3226
|
+
return (options.client ?? client).get({
|
|
3227
|
+
security: [
|
|
3228
|
+
{
|
|
3229
|
+
scheme: "bearer",
|
|
3230
|
+
type: "http"
|
|
3231
|
+
}
|
|
3232
|
+
],
|
|
3233
|
+
url: "/api/v1/projects/{name}/backlinks/sources",
|
|
3234
|
+
...options
|
|
3235
|
+
});
|
|
3236
|
+
};
|
|
3237
|
+
var postApiV1ProjectsByNameBacklinksBingSync = (options) => {
|
|
3238
|
+
return (options.client ?? client).post({
|
|
3239
|
+
security: [
|
|
3240
|
+
{
|
|
3241
|
+
scheme: "bearer",
|
|
3242
|
+
type: "http"
|
|
3243
|
+
}
|
|
3244
|
+
],
|
|
3245
|
+
url: "/api/v1/projects/{name}/backlinks/bing-sync",
|
|
3246
|
+
...options
|
|
3247
|
+
});
|
|
3248
|
+
};
|
|
3136
3249
|
var postApiV1ProjectsByNameTrafficConnectCloudRun = (options) => {
|
|
3137
3250
|
return (options.client ?? client).post({
|
|
3138
3251
|
security: [
|
|
@@ -4129,6 +4242,41 @@ var ApiClient = class {
|
|
|
4129
4242
|
})
|
|
4130
4243
|
);
|
|
4131
4244
|
}
|
|
4245
|
+
async adsConnect(project, body) {
|
|
4246
|
+
return this.invoke(
|
|
4247
|
+
() => postApiV1ProjectsByNameAdsConnect({ client: this.heyClient, path: { name: project }, body })
|
|
4248
|
+
);
|
|
4249
|
+
}
|
|
4250
|
+
async adsDisconnect(project) {
|
|
4251
|
+
return this.invoke(
|
|
4252
|
+
() => deleteApiV1ProjectsByNameAdsConnection({ client: this.heyClient, path: { name: project } })
|
|
4253
|
+
);
|
|
4254
|
+
}
|
|
4255
|
+
async getAdsStatus(project) {
|
|
4256
|
+
return this.invoke(
|
|
4257
|
+
() => getApiV1ProjectsByNameAdsStatus({ client: this.heyClient, path: { name: project } })
|
|
4258
|
+
);
|
|
4259
|
+
}
|
|
4260
|
+
async triggerAdsSync(project) {
|
|
4261
|
+
return this.invoke(
|
|
4262
|
+
() => postApiV1ProjectsByNameAdsSync({ client: this.heyClient, path: { name: project } })
|
|
4263
|
+
);
|
|
4264
|
+
}
|
|
4265
|
+
async getAdsCampaigns(project) {
|
|
4266
|
+
return this.invoke(
|
|
4267
|
+
() => getApiV1ProjectsByNameAdsCampaigns({ client: this.heyClient, path: { name: project } })
|
|
4268
|
+
);
|
|
4269
|
+
}
|
|
4270
|
+
async getAdsInsights(project, query) {
|
|
4271
|
+
return this.invoke(
|
|
4272
|
+
() => getApiV1ProjectsByNameAdsInsights({ client: this.heyClient, path: { name: project }, query })
|
|
4273
|
+
);
|
|
4274
|
+
}
|
|
4275
|
+
async getAdsSummary(project) {
|
|
4276
|
+
return this.invoke(
|
|
4277
|
+
() => getApiV1ProjectsByNameAdsSummary({ client: this.heyClient, path: { name: project } })
|
|
4278
|
+
);
|
|
4279
|
+
}
|
|
4132
4280
|
async listGbpMetrics(project, opts) {
|
|
4133
4281
|
return this.invoke(
|
|
4134
4282
|
() => getApiV1ProjectsByNameGbpMetrics({
|
|
@@ -4937,6 +5085,23 @@ var ApiClient = class {
|
|
|
4937
5085
|
})
|
|
4938
5086
|
);
|
|
4939
5087
|
}
|
|
5088
|
+
async backlinksBingSync(project) {
|
|
5089
|
+
return this.invoke(
|
|
5090
|
+
() => postApiV1ProjectsByNameBacklinksBingSync({
|
|
5091
|
+
client: this.heyClient,
|
|
5092
|
+
path: { name: project }
|
|
5093
|
+
})
|
|
5094
|
+
);
|
|
5095
|
+
}
|
|
5096
|
+
async backlinksSources(project, opts = {}) {
|
|
5097
|
+
return this.invoke(
|
|
5098
|
+
() => getApiV1ProjectsByNameBacklinksSources({
|
|
5099
|
+
client: this.heyClient,
|
|
5100
|
+
path: { name: project },
|
|
5101
|
+
query: { excludeCrawlers: opts.excludeCrawlers ? "1" : void 0 }
|
|
5102
|
+
})
|
|
5103
|
+
);
|
|
5104
|
+
}
|
|
4940
5105
|
async backlinksSummary(project, opts = {}) {
|
|
4941
5106
|
return this.invoke(
|
|
4942
5107
|
() => getApiV1ProjectsByNameBacklinksSummary({
|
|
@@ -4944,7 +5109,8 @@ var ApiClient = class {
|
|
|
4944
5109
|
path: { name: project },
|
|
4945
5110
|
query: {
|
|
4946
5111
|
release: opts.release,
|
|
4947
|
-
excludeCrawlers: opts.excludeCrawlers ? "1" : void 0
|
|
5112
|
+
excludeCrawlers: opts.excludeCrawlers ? "1" : void 0,
|
|
5113
|
+
source: opts.source
|
|
4948
5114
|
}
|
|
4949
5115
|
})
|
|
4950
5116
|
);
|
|
@@ -4958,14 +5124,19 @@ var ApiClient = class {
|
|
|
4958
5124
|
limit: opts.limit,
|
|
4959
5125
|
offset: opts.offset,
|
|
4960
5126
|
release: opts.release,
|
|
4961
|
-
excludeCrawlers: opts.excludeCrawlers ? "1" : void 0
|
|
5127
|
+
excludeCrawlers: opts.excludeCrawlers ? "1" : void 0,
|
|
5128
|
+
source: opts.source
|
|
4962
5129
|
}
|
|
4963
5130
|
})
|
|
4964
5131
|
);
|
|
4965
5132
|
}
|
|
4966
|
-
async backlinksHistory(project) {
|
|
5133
|
+
async backlinksHistory(project, opts = {}) {
|
|
4967
5134
|
return this.invoke(
|
|
4968
|
-
() => getApiV1ProjectsByNameBacklinksHistory({
|
|
5135
|
+
() => getApiV1ProjectsByNameBacklinksHistory({
|
|
5136
|
+
client: this.heyClient,
|
|
5137
|
+
path: { name: project },
|
|
5138
|
+
query: { source: opts.source }
|
|
5139
|
+
})
|
|
4969
5140
|
);
|
|
4970
5141
|
}
|
|
4971
5142
|
};
|
|
@@ -5147,6 +5318,13 @@ var gbpLocationScopedInputSchema = z2.object({
|
|
|
5147
5318
|
var gbpAccountsInputSchema = z2.object({
|
|
5148
5319
|
project: projectNameSchema
|
|
5149
5320
|
});
|
|
5321
|
+
var adsInsightsInputSchema = z2.object({
|
|
5322
|
+
project: projectNameSchema,
|
|
5323
|
+
level: z2.enum(["campaign", "ad_group"]).optional(),
|
|
5324
|
+
entityId: z2.string().optional(),
|
|
5325
|
+
from: z2.string().optional(),
|
|
5326
|
+
to: z2.string().optional()
|
|
5327
|
+
});
|
|
5150
5328
|
var keywordsInputSchema = z2.object({
|
|
5151
5329
|
project: projectNameSchema,
|
|
5152
5330
|
request: keywordBatchRequestSchema
|
|
@@ -5202,7 +5380,11 @@ var contentMapInputSchema = z2.object({
|
|
|
5202
5380
|
var backlinksDomainsInputSchema = z2.object({
|
|
5203
5381
|
project: projectNameSchema,
|
|
5204
5382
|
limit: z2.number().int().positive().max(200).optional().describe("Max linking-domain rows. Default 50, max 200."),
|
|
5205
|
-
release: z2.string().optional().describe("Common Crawl release
|
|
5383
|
+
release: z2.string().optional().describe("Window id (Common Crawl release e.g. cc-main-2026-jan-feb-mar, or Bing window e.g. bing-2026-06-15). Omit for the most recent window with data."),
|
|
5384
|
+
source: backlinkSourceSchema.optional().describe("Backlink source: commoncrawl (default) or bing-webmaster.")
|
|
5385
|
+
});
|
|
5386
|
+
var backlinksSourcesInputSchema = z2.object({
|
|
5387
|
+
project: projectNameSchema
|
|
5206
5388
|
});
|
|
5207
5389
|
var memoryUpsertInputSchema = z2.object({
|
|
5208
5390
|
project: projectNameSchema,
|
|
@@ -5692,7 +5874,7 @@ var canonryMcpTools = [
|
|
|
5692
5874
|
defineTool({
|
|
5693
5875
|
name: "canonry_backlinks_domains",
|
|
5694
5876
|
title: "List backlink domains",
|
|
5695
|
-
description: "
|
|
5877
|
+
description: "Source-aware backlink summary + top linking domains for a project. `source=commoncrawl` (default) reads the most recent ready Common Crawl release; `source=bing-webmaster` reads the latest live Bing Webmaster inbound-link window. Off-site authority signal that correlates with citation likelihood. Returns null summary when the source has no data yet.",
|
|
5696
5878
|
access: "read",
|
|
5697
5879
|
tier: "setup",
|
|
5698
5880
|
inputSchema: backlinksDomainsInputSchema,
|
|
@@ -5700,9 +5882,21 @@ var canonryMcpTools = [
|
|
|
5700
5882
|
openApiOperations: ["GET /api/v1/projects/{name}/backlinks/domains"],
|
|
5701
5883
|
handler: (client2, input) => client2.backlinksDomains(input.project, {
|
|
5702
5884
|
limit: input.limit ?? 50,
|
|
5703
|
-
release: input.release
|
|
5885
|
+
release: input.release,
|
|
5886
|
+
source: input.source
|
|
5704
5887
|
})
|
|
5705
5888
|
}),
|
|
5889
|
+
defineTool({
|
|
5890
|
+
name: "canonry_backlinks_sources",
|
|
5891
|
+
title: "Backlink source availability",
|
|
5892
|
+
description: "Reports which backlink sources are set up for a project (commoncrawl, bing-webmaster): connected, has data, latest window, linking-domain count, and freshness. Use to decide whether to read CC vs Bing or prompt the operator to connect a source.",
|
|
5893
|
+
access: "read",
|
|
5894
|
+
tier: "setup",
|
|
5895
|
+
inputSchema: backlinksSourcesInputSchema,
|
|
5896
|
+
annotations: readAnnotations(),
|
|
5897
|
+
openApiOperations: ["GET /api/v1/projects/{name}/backlinks/sources"],
|
|
5898
|
+
handler: (client2, input) => client2.backlinksSources(input.project)
|
|
5899
|
+
}),
|
|
5706
5900
|
defineTool({
|
|
5707
5901
|
name: "canonry_settings_get",
|
|
5708
5902
|
title: "Get settings",
|
|
@@ -6564,6 +6758,62 @@ var canonryMcpTools = [
|
|
|
6564
6758
|
sitemapUrl: input.sitemapUrl,
|
|
6565
6759
|
limit: input.limit
|
|
6566
6760
|
})
|
|
6761
|
+
}),
|
|
6762
|
+
// ----- OpenAI ads (ChatGPT ads) -----
|
|
6763
|
+
defineTool({
|
|
6764
|
+
name: "canonry_ads_status",
|
|
6765
|
+
title: "OpenAI ads connection status",
|
|
6766
|
+
description: "Connection status and last sync time for the project's OpenAI ad account (ChatGPT ads).",
|
|
6767
|
+
access: "read",
|
|
6768
|
+
tier: "ads",
|
|
6769
|
+
inputSchema: projectInputSchema,
|
|
6770
|
+
annotations: readAnnotations(),
|
|
6771
|
+
openApiOperations: ["GET /api/v1/projects/{name}/ads/status"],
|
|
6772
|
+
handler: (client2, input) => client2.getAdsStatus(input.project)
|
|
6773
|
+
}),
|
|
6774
|
+
defineTool({
|
|
6775
|
+
name: "canonry_ads_campaigns",
|
|
6776
|
+
title: "List synced ad campaigns",
|
|
6777
|
+
description: "Synced campaign snapshots with nested ad groups (context hints \u2014 the targeting primitive) and ads. Paid-surface structure; never conflate with organic cited/mentioned signals.",
|
|
6778
|
+
access: "read",
|
|
6779
|
+
tier: "ads",
|
|
6780
|
+
inputSchema: projectInputSchema,
|
|
6781
|
+
annotations: readAnnotations(),
|
|
6782
|
+
openApiOperations: ["GET /api/v1/projects/{name}/ads/campaigns"],
|
|
6783
|
+
handler: (client2, input) => client2.getAdsCampaigns(input.project)
|
|
6784
|
+
}),
|
|
6785
|
+
defineTool({
|
|
6786
|
+
name: "canonry_ads_insights",
|
|
6787
|
+
title: "Daily paid-performance rollups",
|
|
6788
|
+
description: "Daily paid-performance rollups per level (campaign/ad_group). Spend is integer micros; ctr/cpcMicros are derived server-side (null on zero denominators).",
|
|
6789
|
+
access: "read",
|
|
6790
|
+
tier: "ads",
|
|
6791
|
+
inputSchema: adsInsightsInputSchema,
|
|
6792
|
+
annotations: readAnnotations(),
|
|
6793
|
+
openApiOperations: ["GET /api/v1/projects/{name}/ads/insights"],
|
|
6794
|
+
handler: (client2, input) => client2.getAdsInsights(input.project, compactStringParams(input, ["level", "entityId", "from", "to"]))
|
|
6795
|
+
}),
|
|
6796
|
+
defineTool({
|
|
6797
|
+
name: "canonry_ads_summary",
|
|
6798
|
+
title: "Paid-performance summary",
|
|
6799
|
+
description: "Composite paid summary: campaign/ad-group/ad counts, campaign-level totals (impressions, clicks, spend micros, derived ctr/cpc) and the covered date window.",
|
|
6800
|
+
access: "read",
|
|
6801
|
+
tier: "ads",
|
|
6802
|
+
inputSchema: projectInputSchema,
|
|
6803
|
+
annotations: readAnnotations(),
|
|
6804
|
+
openApiOperations: ["GET /api/v1/projects/{name}/ads/summary"],
|
|
6805
|
+
handler: (client2, input) => client2.getAdsSummary(input.project)
|
|
6806
|
+
}),
|
|
6807
|
+
defineTool({
|
|
6808
|
+
name: "canonry_ads_sync",
|
|
6809
|
+
title: "Trigger ads sync",
|
|
6810
|
+
description: "Trigger an ads-sync run (entity snapshots + daily paid-performance rollups) for the connected OpenAI ad account. Returns the run id; poll canonry_run_get for status.",
|
|
6811
|
+
access: "write",
|
|
6812
|
+
tier: "ads",
|
|
6813
|
+
inputSchema: projectInputSchema,
|
|
6814
|
+
annotations: writeAnnotations({ idempotentHint: true }),
|
|
6815
|
+
openApiOperations: ["POST /api/v1/projects/{name}/ads/sync"],
|
|
6816
|
+
handler: (client2, input) => client2.triggerAdsSync(input.project)
|
|
6567
6817
|
})
|
|
6568
6818
|
];
|
|
6569
6819
|
var CANONRY_MCP_TOOL_COUNT = canonryMcpTools.length;
|
|
@@ -383,7 +383,8 @@ var runKindSchema = z3.enum([
|
|
|
383
383
|
"traffic-sync",
|
|
384
384
|
"aeo-discover-seed",
|
|
385
385
|
"aeo-discover-probe",
|
|
386
|
-
"gbp-sync"
|
|
386
|
+
"gbp-sync",
|
|
387
|
+
"ads-sync"
|
|
387
388
|
]);
|
|
388
389
|
var RunKinds = runKindSchema.enum;
|
|
389
390
|
var runTriggerSchema = z3.enum(["manual", "scheduled", "config-apply", "backfill", "probe"]);
|
|
@@ -1618,7 +1619,7 @@ var siteAuditRunResponseSchema = z14.object({
|
|
|
1618
1619
|
|
|
1619
1620
|
// ../contracts/src/schedule.ts
|
|
1620
1621
|
import { z as z15 } from "zod";
|
|
1621
|
-
var schedulableRunKindSchema = z15.enum(["answer-visibility", "traffic-sync", "gbp-sync", "data-refresh", "backlinks-sync", "site-audit"]);
|
|
1622
|
+
var schedulableRunKindSchema = z15.enum(["answer-visibility", "traffic-sync", "gbp-sync", "data-refresh", "backlinks-sync", "site-audit", "ads-sync"]);
|
|
1622
1623
|
var SchedulableRunKinds = schedulableRunKindSchema.enum;
|
|
1623
1624
|
var scheduleDtoSchema = z15.object({
|
|
1624
1625
|
id: z15.string(),
|
|
@@ -2500,6 +2501,22 @@ var agentMemoryDeleteRequestSchema = z21.object({
|
|
|
2500
2501
|
|
|
2501
2502
|
// ../contracts/src/backlinks.ts
|
|
2502
2503
|
import { z as z22 } from "zod";
|
|
2504
|
+
var backlinkSourceSchema = z22.enum(["commoncrawl", "bing-webmaster"]);
|
|
2505
|
+
var BacklinkSources = backlinkSourceSchema.enum;
|
|
2506
|
+
function computeBacklinkSummaryMetrics(rows) {
|
|
2507
|
+
if (rows.length === 0) {
|
|
2508
|
+
return { totalLinkingDomains: 0, totalHosts: 0, top10HostsShare: "0" };
|
|
2509
|
+
}
|
|
2510
|
+
const sorted = [...rows].sort((a, b) => b.numHosts - a.numHosts);
|
|
2511
|
+
const totalHosts = sorted.reduce((acc, r) => acc + r.numHosts, 0);
|
|
2512
|
+
const top10Hosts = sorted.slice(0, 10).reduce((acc, r) => acc + r.numHosts, 0);
|
|
2513
|
+
const share = totalHosts > 0 ? top10Hosts / totalHosts : 0;
|
|
2514
|
+
return {
|
|
2515
|
+
totalLinkingDomains: rows.length,
|
|
2516
|
+
totalHosts,
|
|
2517
|
+
top10HostsShare: share.toFixed(6)
|
|
2518
|
+
};
|
|
2519
|
+
}
|
|
2503
2520
|
var ccReleaseSyncStatusSchema = z22.enum(["queued", "downloading", "querying", "ready", "failed"]);
|
|
2504
2521
|
var CcReleaseSyncStatuses = ccReleaseSyncStatusSchema.enum;
|
|
2505
2522
|
var ccReleaseSyncDtoSchema = z22.object({
|
|
@@ -2525,16 +2542,24 @@ var ccReleaseSyncDtoSchema = z22.object({
|
|
|
2525
2542
|
});
|
|
2526
2543
|
var backlinkDomainDtoSchema = z22.object({
|
|
2527
2544
|
linkingDomain: z22.string(),
|
|
2528
|
-
|
|
2545
|
+
// For Common Crawl this is the count of distinct hosts within the linking
|
|
2546
|
+
// domain; for Bing Webmaster it is the count of distinct linking pages (URLs)
|
|
2547
|
+
// from that linking host. Read alongside `source` — the unit differs per source.
|
|
2548
|
+
numHosts: z22.number().int(),
|
|
2549
|
+
source: backlinkSourceSchema
|
|
2529
2550
|
});
|
|
2530
2551
|
var backlinkSummaryDtoSchema = z22.object({
|
|
2531
2552
|
projectId: z22.string(),
|
|
2553
|
+
// Window identifier. Common Crawl uses the release slug
|
|
2554
|
+
// (`cc-main-YYYY-<mon>-<mon>-<mon>`); Bing Webmaster uses a synthetic
|
|
2555
|
+
// per-sync-day window (`bing-YYYY-MM-DD`).
|
|
2532
2556
|
release: z22.string(),
|
|
2533
2557
|
targetDomain: z22.string(),
|
|
2534
2558
|
totalLinkingDomains: z22.number().int(),
|
|
2535
2559
|
totalHosts: z22.number().int(),
|
|
2536
2560
|
top10HostsShare: z22.string(),
|
|
2537
2561
|
queriedAt: z22.string(),
|
|
2562
|
+
source: backlinkSourceSchema,
|
|
2538
2563
|
// Populated when the response is filtered (e.g. ?excludeCrawlers=1).
|
|
2539
2564
|
// Counts the rows omitted from totalLinkingDomains/totalHosts so callers
|
|
2540
2565
|
// can show "N hidden" hints without re-deriving them.
|
|
@@ -2542,6 +2567,9 @@ var backlinkSummaryDtoSchema = z22.object({
|
|
|
2542
2567
|
excludedHosts: z22.number().int().optional()
|
|
2543
2568
|
});
|
|
2544
2569
|
var backlinkListResponseSchema = z22.object({
|
|
2570
|
+
// The source this response was filtered to (defaults to commoncrawl when the
|
|
2571
|
+
// caller omits `?source`).
|
|
2572
|
+
source: backlinkSourceSchema,
|
|
2545
2573
|
summary: backlinkSummaryDtoSchema.nullable(),
|
|
2546
2574
|
total: z22.number().int(),
|
|
2547
2575
|
rows: z22.array(backlinkDomainDtoSchema)
|
|
@@ -2551,7 +2579,38 @@ var backlinkHistoryEntrySchema = z22.object({
|
|
|
2551
2579
|
totalLinkingDomains: z22.number().int(),
|
|
2552
2580
|
totalHosts: z22.number().int(),
|
|
2553
2581
|
top10HostsShare: z22.string(),
|
|
2554
|
-
queriedAt: z22.string()
|
|
2582
|
+
queriedAt: z22.string(),
|
|
2583
|
+
source: backlinkSourceSchema
|
|
2584
|
+
});
|
|
2585
|
+
var backlinkSourceAvailabilityDtoSchema = z22.object({
|
|
2586
|
+
source: backlinkSourceSchema,
|
|
2587
|
+
/**
|
|
2588
|
+
* The source is set up for this project:
|
|
2589
|
+
* - commoncrawl: `autoExtractBacklinks` enabled AND a `ready` release sync exists.
|
|
2590
|
+
* - bing-webmaster: a Bing Webmaster connection exists for the project domain.
|
|
2591
|
+
*/
|
|
2592
|
+
connected: z22.boolean(),
|
|
2593
|
+
/** Backlink rows exist for this project + source. */
|
|
2594
|
+
hasData: z22.boolean(),
|
|
2595
|
+
/** Latest window id with data for this source, null when none. */
|
|
2596
|
+
latestRelease: z22.string().nullable(),
|
|
2597
|
+
/**
|
|
2598
|
+
* Linking-domain count in the latest window. Excludes crawler/proxy hosts only
|
|
2599
|
+
* when the request sets `?excludeCrawlers=1` (default off, matching the summary
|
|
2600
|
+
* and domains endpoints); the dashboard passes it so the switcher pill matches
|
|
2601
|
+
* the metric card.
|
|
2602
|
+
*/
|
|
2603
|
+
totalLinkingDomains: z22.number().int(),
|
|
2604
|
+
/** Freshness: `queriedAt` of the latest summary for this source, null when none. */
|
|
2605
|
+
lastSyncedAt: z22.string().nullable()
|
|
2606
|
+
});
|
|
2607
|
+
var backlinkSourcesResponseSchema = z22.object({
|
|
2608
|
+
projectId: z22.string(),
|
|
2609
|
+
targetDomain: z22.string(),
|
|
2610
|
+
/** Availability for every known source, in a stable order. */
|
|
2611
|
+
sources: z22.array(backlinkSourceAvailabilityDtoSchema),
|
|
2612
|
+
anyConnected: z22.boolean(),
|
|
2613
|
+
anyData: z22.boolean()
|
|
2555
2614
|
});
|
|
2556
2615
|
var backlinksInstallStatusDtoSchema = z22.object({
|
|
2557
2616
|
duckdbInstalled: z22.boolean(),
|
|
@@ -3022,6 +3081,17 @@ function absolutizeProjectUrl(url, canonicalDomain) {
|
|
|
3022
3081
|
if (trimmed.startsWith("/")) return `https://${host}${trimmed}`;
|
|
3023
3082
|
return `https://${host}/${trimmed}`;
|
|
3024
3083
|
}
|
|
3084
|
+
function hostOf(value) {
|
|
3085
|
+
if (value == null) return null;
|
|
3086
|
+
const trimmed = value.trim();
|
|
3087
|
+
if (!trimmed) return null;
|
|
3088
|
+
try {
|
|
3089
|
+
const url = trimmed.includes("://") ? new URL(trimmed) : new URL(`https://${trimmed}`);
|
|
3090
|
+
return url.hostname.replace(/^www\./, "").toLowerCase();
|
|
3091
|
+
} catch {
|
|
3092
|
+
return null;
|
|
3093
|
+
}
|
|
3094
|
+
}
|
|
3025
3095
|
function normalizeUrlPath(input) {
|
|
3026
3096
|
if (input == null) return null;
|
|
3027
3097
|
let trimmed = input.trim();
|
|
@@ -4257,6 +4327,129 @@ function formatDeltaCopy(d, suffix, windowLabel = "vs prior 7 days") {
|
|
|
4257
4327
|
return `Flat ${windowLabel} (${formatNumber(d.prior)} ${suffix})`;
|
|
4258
4328
|
}
|
|
4259
4329
|
|
|
4330
|
+
// ../contracts/src/ads.ts
|
|
4331
|
+
import { z as z30 } from "zod";
|
|
4332
|
+
var adsConnectRequestSchema = z30.object({
|
|
4333
|
+
/** Ads Manager "SDK key" scoped to one ad account. Stored in config.yaml, never the DB. */
|
|
4334
|
+
apiKey: z30.string().min(1)
|
|
4335
|
+
});
|
|
4336
|
+
var adsConnectionStatusDtoSchema = z30.object({
|
|
4337
|
+
connected: z30.boolean(),
|
|
4338
|
+
adAccountId: z30.string().nullable().optional(),
|
|
4339
|
+
displayName: z30.string().nullable().optional(),
|
|
4340
|
+
currencyCode: z30.string().nullable().optional(),
|
|
4341
|
+
timezone: z30.string().nullable().optional(),
|
|
4342
|
+
status: z30.string().nullable().optional(),
|
|
4343
|
+
lastSyncedAt: z30.string().nullable().optional()
|
|
4344
|
+
});
|
|
4345
|
+
var adsDisconnectResponseSchema = z30.object({
|
|
4346
|
+
disconnected: z30.boolean()
|
|
4347
|
+
});
|
|
4348
|
+
var adsSyncResponseSchema = z30.object({
|
|
4349
|
+
runId: z30.string(),
|
|
4350
|
+
status: z30.string()
|
|
4351
|
+
});
|
|
4352
|
+
var adsCreativeDtoSchema = z30.object({
|
|
4353
|
+
type: z30.string().nullable().optional(),
|
|
4354
|
+
title: z30.string().nullable().optional(),
|
|
4355
|
+
body: z30.string().nullable().optional(),
|
|
4356
|
+
targetUrl: z30.string().nullable().optional()
|
|
4357
|
+
});
|
|
4358
|
+
var adsAdDtoSchema = z30.object({
|
|
4359
|
+
id: z30.string(),
|
|
4360
|
+
adGroupId: z30.string(),
|
|
4361
|
+
name: z30.string(),
|
|
4362
|
+
status: z30.string(),
|
|
4363
|
+
reviewStatus: z30.string().nullable().optional(),
|
|
4364
|
+
creative: adsCreativeDtoSchema.nullable().optional()
|
|
4365
|
+
});
|
|
4366
|
+
var adsAdGroupDtoSchema = z30.object({
|
|
4367
|
+
id: z30.string(),
|
|
4368
|
+
campaignId: z30.string(),
|
|
4369
|
+
name: z30.string(),
|
|
4370
|
+
status: z30.string(),
|
|
4371
|
+
billingEventType: z30.string().nullable().optional(),
|
|
4372
|
+
maxBidMicros: z30.number().int().nullable().optional(),
|
|
4373
|
+
/**
|
|
4374
|
+
* The targeting primitive: entries are multi-line strings of
|
|
4375
|
+
* newline-separated example queries (the live Ads Manager format).
|
|
4376
|
+
*/
|
|
4377
|
+
contextHints: z30.array(z30.string()).default([]),
|
|
4378
|
+
ads: z30.array(adsAdDtoSchema).default([])
|
|
4379
|
+
});
|
|
4380
|
+
var adsCampaignDtoSchema = z30.object({
|
|
4381
|
+
id: z30.string(),
|
|
4382
|
+
name: z30.string(),
|
|
4383
|
+
status: z30.string(),
|
|
4384
|
+
biddingType: z30.string().nullable().optional(),
|
|
4385
|
+
dailySpendLimitMicros: z30.number().int().nullable().optional(),
|
|
4386
|
+
lifetimeSpendLimitMicros: z30.number().int().nullable().optional(),
|
|
4387
|
+
adGroups: z30.array(adsAdGroupDtoSchema).default([])
|
|
4388
|
+
});
|
|
4389
|
+
var adsCampaignListResponseSchema = z30.object({
|
|
4390
|
+
campaigns: z30.array(adsCampaignDtoSchema)
|
|
4391
|
+
});
|
|
4392
|
+
var adsInsightLevelSchema = z30.enum(["campaign", "ad_group"]);
|
|
4393
|
+
var AdsInsightLevels = adsInsightLevelSchema.enum;
|
|
4394
|
+
var adsInsightRowDtoSchema = z30.object({
|
|
4395
|
+
level: adsInsightLevelSchema,
|
|
4396
|
+
entityId: z30.string(),
|
|
4397
|
+
date: z30.string(),
|
|
4398
|
+
impressions: z30.number().int(),
|
|
4399
|
+
clicks: z30.number().int(),
|
|
4400
|
+
spendMicros: z30.number().int(),
|
|
4401
|
+
/** clicks / impressions; null when impressions is 0. */
|
|
4402
|
+
ctr: z30.number().nullable(),
|
|
4403
|
+
/** spendMicros / clicks, rounded to integer micros; null when clicks is 0. */
|
|
4404
|
+
cpcMicros: z30.number().int().nullable()
|
|
4405
|
+
});
|
|
4406
|
+
var adsInsightsResponseSchema = z30.object({
|
|
4407
|
+
rows: z30.array(adsInsightRowDtoSchema),
|
|
4408
|
+
/** Account currency for rendering spend/cpc; null before the first sync. */
|
|
4409
|
+
currencyCode: z30.string().nullable().optional()
|
|
4410
|
+
});
|
|
4411
|
+
var adsTotalsDtoSchema = z30.object({
|
|
4412
|
+
impressions: z30.number().int(),
|
|
4413
|
+
clicks: z30.number().int(),
|
|
4414
|
+
spendMicros: z30.number().int(),
|
|
4415
|
+
ctr: z30.number().nullable(),
|
|
4416
|
+
cpcMicros: z30.number().int().nullable()
|
|
4417
|
+
});
|
|
4418
|
+
var adsSummaryDtoSchema = z30.object({
|
|
4419
|
+
connected: z30.boolean(),
|
|
4420
|
+
displayName: z30.string().nullable().optional(),
|
|
4421
|
+
currencyCode: z30.string().nullable().optional(),
|
|
4422
|
+
lastSyncedAt: z30.string().nullable().optional(),
|
|
4423
|
+
campaignCount: z30.number().int(),
|
|
4424
|
+
adGroupCount: z30.number().int(),
|
|
4425
|
+
adCount: z30.number().int(),
|
|
4426
|
+
/** Date range the totals cover (oldest/newest rollup date), null when empty. */
|
|
4427
|
+
window: z30.object({
|
|
4428
|
+
from: z30.string().nullable(),
|
|
4429
|
+
to: z30.string().nullable()
|
|
4430
|
+
}),
|
|
4431
|
+
/** Campaign-level rollup totals over the window (levels are not summed across). */
|
|
4432
|
+
totals: adsTotalsDtoSchema
|
|
4433
|
+
});
|
|
4434
|
+
function adsCtr(clicks, impressions) {
|
|
4435
|
+
return impressions > 0 ? clicks / impressions : null;
|
|
4436
|
+
}
|
|
4437
|
+
function adsCpcMicros(spendMicros, clicks) {
|
|
4438
|
+
return clicks > 0 ? Math.round(spendMicros / clicks) : null;
|
|
4439
|
+
}
|
|
4440
|
+
|
|
4441
|
+
// ../contracts/src/money.ts
|
|
4442
|
+
var MICROS_PER_UNIT = 1e6;
|
|
4443
|
+
function dollarsToMicros(dollars) {
|
|
4444
|
+
return Math.round(dollars * MICROS_PER_UNIT);
|
|
4445
|
+
}
|
|
4446
|
+
function formatMicros(micros, currencyCode = "USD") {
|
|
4447
|
+
return new Intl.NumberFormat("en-US", {
|
|
4448
|
+
style: "currency",
|
|
4449
|
+
currency: currencyCode
|
|
4450
|
+
}).format(micros / MICROS_PER_UNIT);
|
|
4451
|
+
}
|
|
4452
|
+
|
|
4260
4453
|
// ../contracts/src/ai-engines.ts
|
|
4261
4454
|
var AI_ENGINE_DOMAINS = {
|
|
4262
4455
|
/** OpenAI marketing/blog/API surface. */
|
|
@@ -4486,11 +4679,15 @@ export {
|
|
|
4486
4679
|
AGENT_MEMORY_KEY_MAX_LENGTH,
|
|
4487
4680
|
agentMemoryUpsertRequestSchema,
|
|
4488
4681
|
agentMemoryDeleteRequestSchema,
|
|
4682
|
+
backlinkSourceSchema,
|
|
4683
|
+
BacklinkSources,
|
|
4684
|
+
computeBacklinkSummaryMetrics,
|
|
4489
4685
|
CcReleaseSyncStatuses,
|
|
4490
4686
|
ccReleaseSyncDtoSchema,
|
|
4491
4687
|
backlinkSummaryDtoSchema,
|
|
4492
4688
|
backlinkListResponseSchema,
|
|
4493
4689
|
backlinkHistoryEntrySchema,
|
|
4690
|
+
backlinkSourcesResponseSchema,
|
|
4494
4691
|
backlinksInstallStatusDtoSchema,
|
|
4495
4692
|
backlinksInstallResultDtoSchema,
|
|
4496
4693
|
ccAvailableReleaseSchema,
|
|
@@ -4519,6 +4716,7 @@ export {
|
|
|
4519
4716
|
doctorReportSchema,
|
|
4520
4717
|
summarizeCheckResults,
|
|
4521
4718
|
absolutizeProjectUrl,
|
|
4719
|
+
hostOf,
|
|
4522
4720
|
normalizeUrlPath,
|
|
4523
4721
|
citationVisibilityResponseSchema,
|
|
4524
4722
|
emptyCitationVisibility,
|
|
@@ -4566,6 +4764,18 @@ export {
|
|
|
4566
4764
|
deltaPercent,
|
|
4567
4765
|
deltaTone,
|
|
4568
4766
|
formatDeltaCopy,
|
|
4767
|
+
adsConnectRequestSchema,
|
|
4768
|
+
adsConnectionStatusDtoSchema,
|
|
4769
|
+
adsDisconnectResponseSchema,
|
|
4770
|
+
adsSyncResponseSchema,
|
|
4771
|
+
adsCampaignListResponseSchema,
|
|
4772
|
+
adsInsightLevelSchema,
|
|
4773
|
+
adsInsightsResponseSchema,
|
|
4774
|
+
adsSummaryDtoSchema,
|
|
4775
|
+
adsCtr,
|
|
4776
|
+
adsCpcMicros,
|
|
4777
|
+
dollarsToMicros,
|
|
4778
|
+
formatMicros,
|
|
4569
4779
|
AI_ENGINE_DOMAINS,
|
|
4570
4780
|
AI_ENGINE_SELF_DOMAINS,
|
|
4571
4781
|
VERTEX_AI_SEARCH_PROXY_DOMAIN,
|