@canonry/canonry 4.155.0 → 4.157.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/README.md +2 -2
- package/assets/agent-workspace/skills/aero/references/orchestration.md +1 -1
- package/assets/agent-workspace/skills/canonry/SKILL.md +9 -4
- package/assets/agent-workspace/skills/canonry/references/canonry-cli.md +14 -2
- package/assets/agent-workspace/skills/canonry/references/server-side-traffic.md +454 -21
- package/assets/assets/{AuditHistoryPanel-BlbMBxOY.js → AuditHistoryPanel-D12lHs6n.js} +1 -1
- package/assets/assets/{BacklinksPage-DA9EaV9q.js → BacklinksPage-D2ScFYru.js} +1 -1
- package/assets/assets/{HistoryPage-BTrIHjMQ.js → HistoryPage-jZ_I4rwX.js} +1 -1
- package/assets/assets/{MeasurementPropertyPage-CN6o5xFg.js → MeasurementPropertyPage-BIdQjXJT.js} +1 -1
- package/assets/assets/ProjectPage-CLvLOOtj.js +15 -0
- package/assets/assets/{RunRow-ch_OlCPs.js → RunRow-Q2X0NR74.js} +1 -1
- package/assets/assets/{RunsPage-T89Y_yS8.js → RunsPage-Cw7YVsbJ.js} +1 -1
- package/assets/assets/{SettingsPage-DnmEq3F9.js → SettingsPage-bFl2EXOD.js} +1 -1
- package/assets/assets/{TrafficPage-CW1UhaJt.js → TrafficPage-DJjhk7Jw.js} +1 -1
- package/assets/assets/{TrafficSourceDetailPage-r4Ji3wJm.js → TrafficSourceDetailPage-CGKwIu9A.js} +1 -1
- package/assets/assets/{extract-error-message-a8EErBoZ.js → extract-error-message-BHm98tXH.js} +1 -1
- package/assets/assets/index-BxegEwic.css +1 -0
- package/assets/assets/index-VO6nKq5b.js +83 -0
- package/assets/assets/react-sigma_core.esm.min-EzswMBkr.js +312 -0
- package/assets/assets/vendor-lucide-BtYdosYk.js +1 -0
- package/assets/assets/{vendor-markdown-CpDJch4G.js → vendor-markdown-D274_wsI.js} +1 -1
- package/assets/assets/{vendor-radix-DnzzbllM.js → vendor-radix-BxMXSwbC.js} +1 -1
- package/assets/assets/{vendor-recharts-33ACLxsD.js → vendor-recharts-C4ktw_aE.js} +1 -1
- package/assets/assets/{vendor-tanstack-BjS7iY3g.js → vendor-tanstack-pFxw0eGP.js} +1 -1
- package/assets/index.html +7 -7
- package/dist/{chunk-YSESZNVT.js → chunk-AEIKAWOW.js} +795 -239
- package/dist/{chunk-OSHRDV36.js → chunk-KMTRO56O.js} +281 -1
- package/dist/{chunk-VOL2BSM5.js → chunk-MEBL4EJO.js} +3030 -338
- package/dist/{chunk-VIKPFI6F.js → chunk-TRRVBTU5.js} +399 -1
- package/dist/cli.js +1087 -140
- package/dist/index.d.ts +32 -0
- package/dist/index.js +4 -4
- package/dist/{intelligence-service-G4NV3X36.js → intelligence-service-YUUPSJRC.js} +2 -2
- package/dist/mcp.js +4 -4
- package/package.json +13 -10
- package/assets/assets/ProjectPage-CsDbgp_0.js +0 -12
- package/assets/assets/index-BKq6k5Of.js +0 -83
- package/assets/assets/index-DyL54s8x.css +0 -1
- package/assets/assets/vendor-lucide-ByU7vBHt.js +0 -1
|
@@ -81,7 +81,7 @@ import {
|
|
|
81
81
|
trafficConnectWordpressRequestSchema,
|
|
82
82
|
trafficEventKindSchema,
|
|
83
83
|
trafficSeriesGranularitySchema
|
|
84
|
-
} from "./chunk-
|
|
84
|
+
} from "./chunk-TRRVBTU5.js";
|
|
85
85
|
|
|
86
86
|
// src/config.ts
|
|
87
87
|
import fs from "fs";
|
|
@@ -107,6 +107,14 @@ function normalizeWordpressConfig(config) {
|
|
|
107
107
|
defaultEnv: connection.defaultEnv ?? "live"
|
|
108
108
|
}));
|
|
109
109
|
}
|
|
110
|
+
function normalizeCloudflareTrafficConfig(config) {
|
|
111
|
+
for (const connection of config.cloudflareTraffic?.connections ?? []) {
|
|
112
|
+
const legacy = connection;
|
|
113
|
+
if (legacy.deliveryMode === void 0) {
|
|
114
|
+
legacy.deliveryMode = "direct-push";
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
}
|
|
110
118
|
function getConfigDir() {
|
|
111
119
|
const override = process.env.CANONRY_CONFIG_DIR?.trim();
|
|
112
120
|
if (override) {
|
|
@@ -152,6 +160,7 @@ Do not write config.yaml by hand; use "canonry init", "canonry settings", or "ca
|
|
|
152
160
|
}
|
|
153
161
|
normalizeGoogleConfig(parsed);
|
|
154
162
|
normalizeWordpressConfig(parsed);
|
|
163
|
+
normalizeCloudflareTrafficConfig(parsed);
|
|
155
164
|
const portOverride = process.env.CANONRY_PORT?.trim();
|
|
156
165
|
if (portOverride) {
|
|
157
166
|
try {
|
|
@@ -4695,6 +4704,22 @@ var postApiV1ProjectsByNameTrafficConnectVercel = (options) => {
|
|
|
4695
4704
|
}
|
|
4696
4705
|
});
|
|
4697
4706
|
};
|
|
4707
|
+
var postApiV1ProjectsByNameTrafficConnectCloudflare = (options) => {
|
|
4708
|
+
return (options.client ?? client).post({
|
|
4709
|
+
security: [
|
|
4710
|
+
{
|
|
4711
|
+
scheme: "bearer",
|
|
4712
|
+
type: "http"
|
|
4713
|
+
}
|
|
4714
|
+
],
|
|
4715
|
+
url: "/api/v1/projects/{name}/traffic/connect/cloudflare",
|
|
4716
|
+
...options,
|
|
4717
|
+
headers: {
|
|
4718
|
+
"Content-Type": "application/json",
|
|
4719
|
+
...options.headers
|
|
4720
|
+
}
|
|
4721
|
+
});
|
|
4722
|
+
};
|
|
4698
4723
|
var postApiV1ProjectsByNameTrafficSourcesByIdSync = (options) => {
|
|
4699
4724
|
return (options.client ?? client).post({
|
|
4700
4725
|
security: [
|
|
@@ -4919,6 +4944,54 @@ var getApiV1ProjectsByNameTechnicalAeoCrawl = (options) => {
|
|
|
4919
4944
|
...options
|
|
4920
4945
|
});
|
|
4921
4946
|
};
|
|
4947
|
+
var getApiV1ProjectsByNameTechnicalAeoSubgraph = (options) => {
|
|
4948
|
+
return (options.client ?? client).get({
|
|
4949
|
+
security: [
|
|
4950
|
+
{
|
|
4951
|
+
scheme: "bearer",
|
|
4952
|
+
type: "http"
|
|
4953
|
+
}
|
|
4954
|
+
],
|
|
4955
|
+
url: "/api/v1/projects/{name}/technical-aeo/subgraph",
|
|
4956
|
+
...options
|
|
4957
|
+
});
|
|
4958
|
+
};
|
|
4959
|
+
var getApiV1ProjectsByNameTechnicalAeoPath = (options) => {
|
|
4960
|
+
return (options.client ?? client).get({
|
|
4961
|
+
security: [
|
|
4962
|
+
{
|
|
4963
|
+
scheme: "bearer",
|
|
4964
|
+
type: "http"
|
|
4965
|
+
}
|
|
4966
|
+
],
|
|
4967
|
+
url: "/api/v1/projects/{name}/technical-aeo/path",
|
|
4968
|
+
...options
|
|
4969
|
+
});
|
|
4970
|
+
};
|
|
4971
|
+
var getApiV1ProjectsByNameTechnicalAeoChanges = (options) => {
|
|
4972
|
+
return (options.client ?? client).get({
|
|
4973
|
+
security: [
|
|
4974
|
+
{
|
|
4975
|
+
scheme: "bearer",
|
|
4976
|
+
type: "http"
|
|
4977
|
+
}
|
|
4978
|
+
],
|
|
4979
|
+
url: "/api/v1/projects/{name}/technical-aeo/changes",
|
|
4980
|
+
...options
|
|
4981
|
+
});
|
|
4982
|
+
};
|
|
4983
|
+
var getApiV1ProjectsByNameTechnicalAeoCrawlPagesAudit = (options) => {
|
|
4984
|
+
return (options.client ?? client).get({
|
|
4985
|
+
security: [
|
|
4986
|
+
{
|
|
4987
|
+
scheme: "bearer",
|
|
4988
|
+
type: "http"
|
|
4989
|
+
}
|
|
4990
|
+
],
|
|
4991
|
+
url: "/api/v1/projects/{name}/technical-aeo/crawl/pages/audit",
|
|
4992
|
+
...options
|
|
4993
|
+
});
|
|
4994
|
+
};
|
|
4922
4995
|
var getApiV1ProjectsByNameTechnicalAeoCrawlPages = (options) => {
|
|
4923
4996
|
return (options.client ?? client).get({
|
|
4924
4997
|
security: [
|
|
@@ -6934,6 +7007,15 @@ var ApiClient = class {
|
|
|
6934
7007
|
})
|
|
6935
7008
|
);
|
|
6936
7009
|
}
|
|
7010
|
+
async trafficConnectCloudflare(project, body) {
|
|
7011
|
+
return this.invoke(
|
|
7012
|
+
() => postApiV1ProjectsByNameTrafficConnectCloudflare({
|
|
7013
|
+
client: this.heyClient,
|
|
7014
|
+
path: { name: project },
|
|
7015
|
+
body
|
|
7016
|
+
})
|
|
7017
|
+
);
|
|
7018
|
+
}
|
|
6937
7019
|
async trafficSync(project, sourceId, body) {
|
|
6938
7020
|
return this.invoke(
|
|
6939
7021
|
() => postApiV1ProjectsByNameTrafficSourcesByIdSync({
|
|
@@ -7123,6 +7205,57 @@ var ApiClient = class {
|
|
|
7123
7205
|
})
|
|
7124
7206
|
);
|
|
7125
7207
|
}
|
|
7208
|
+
/** Bounded semantic Site Health neighborhood; this never returns visualization layout. */
|
|
7209
|
+
async getSiteHealthSubgraph(project, opts) {
|
|
7210
|
+
return this.invoke(
|
|
7211
|
+
() => getApiV1ProjectsByNameTechnicalAeoSubgraph({
|
|
7212
|
+
client: this.heyClient,
|
|
7213
|
+
path: { name: project },
|
|
7214
|
+
query: {
|
|
7215
|
+
runId: opts?.runId,
|
|
7216
|
+
nodeKey: opts?.nodeKey,
|
|
7217
|
+
url: opts?.url,
|
|
7218
|
+
hops: opts?.hops,
|
|
7219
|
+
maxNodes: opts?.maxNodes,
|
|
7220
|
+
maxEdges: opts?.maxEdges
|
|
7221
|
+
}
|
|
7222
|
+
})
|
|
7223
|
+
);
|
|
7224
|
+
}
|
|
7225
|
+
/** Directed shortest path over persisted, followable internal links. */
|
|
7226
|
+
async getSiteHealthPath(project, opts) {
|
|
7227
|
+
return this.invoke(
|
|
7228
|
+
() => getApiV1ProjectsByNameTechnicalAeoPath({
|
|
7229
|
+
client: this.heyClient,
|
|
7230
|
+
path: { name: project },
|
|
7231
|
+
query: {
|
|
7232
|
+
runId: opts.runId,
|
|
7233
|
+
fromNodeKey: opts.fromNodeKey,
|
|
7234
|
+
fromUrl: opts.fromUrl,
|
|
7235
|
+
toNodeKey: opts.toNodeKey,
|
|
7236
|
+
toUrl: opts.toUrl,
|
|
7237
|
+
maxDepth: opts.maxDepth
|
|
7238
|
+
}
|
|
7239
|
+
})
|
|
7240
|
+
);
|
|
7241
|
+
}
|
|
7242
|
+
/** Cursor-paged canonical page/link changes between immutable complete crawls. */
|
|
7243
|
+
async getSiteHealthChanges(project, opts) {
|
|
7244
|
+
return this.invoke(
|
|
7245
|
+
() => getApiV1ProjectsByNameTechnicalAeoChanges({
|
|
7246
|
+
client: this.heyClient,
|
|
7247
|
+
path: { name: project },
|
|
7248
|
+
query: {
|
|
7249
|
+
fromRunId: opts?.fromRunId,
|
|
7250
|
+
toRunId: opts?.toRunId,
|
|
7251
|
+
scope: opts?.scope,
|
|
7252
|
+
change: opts?.change,
|
|
7253
|
+
cursor: opts?.cursor,
|
|
7254
|
+
limit: opts?.limit
|
|
7255
|
+
}
|
|
7256
|
+
})
|
|
7257
|
+
);
|
|
7258
|
+
}
|
|
7126
7259
|
/** Bounded, cursor-paged crawl nodes. */
|
|
7127
7260
|
async getTechnicalAeoCrawlPages(project, opts) {
|
|
7128
7261
|
return this.invoke(
|
|
@@ -7142,6 +7275,20 @@ var ApiClient = class {
|
|
|
7142
7275
|
})
|
|
7143
7276
|
);
|
|
7144
7277
|
}
|
|
7278
|
+
/** Exact page-scoped audit evidence tied to a persisted crawl node. */
|
|
7279
|
+
async getTechnicalAeoPageAudit(project, opts) {
|
|
7280
|
+
return this.invoke(
|
|
7281
|
+
() => getApiV1ProjectsByNameTechnicalAeoCrawlPagesAudit({
|
|
7282
|
+
client: this.heyClient,
|
|
7283
|
+
path: { name: project },
|
|
7284
|
+
query: {
|
|
7285
|
+
runId: opts.runId,
|
|
7286
|
+
nodeKey: opts.nodeKey,
|
|
7287
|
+
url: opts.url
|
|
7288
|
+
}
|
|
7289
|
+
})
|
|
7290
|
+
);
|
|
7291
|
+
}
|
|
7145
7292
|
/** One bounded path level from a persisted crawl. */
|
|
7146
7293
|
async getTechnicalAeoStructure(project, opts) {
|
|
7147
7294
|
return this.invoke(
|
|
@@ -8375,6 +8522,59 @@ var technicalAeoCrawlInputSchema = z3.object({
|
|
|
8375
8522
|
project: projectNameSchema,
|
|
8376
8523
|
runId: runIdSchema.optional().describe("Historical crawl-bearing site-audit run ID. Omit for the latest persisted crawl.")
|
|
8377
8524
|
});
|
|
8525
|
+
var siteHealthPageAuditInputSchema = z3.object({
|
|
8526
|
+
project: projectNameSchema,
|
|
8527
|
+
runId: runIdSchema.optional().describe("Historical crawl-bearing site-audit run ID. Omit for the latest persisted crawl."),
|
|
8528
|
+
nodeKey: z3.string().min(1).optional().describe("Exact crawl node key, as returned by Site Health page or subgraph reads."),
|
|
8529
|
+
url: z3.string().url().optional().describe("Exact page URL. Use this only when a crawl node key is unavailable.")
|
|
8530
|
+
}).refine((value) => Boolean(value.nodeKey || value.url), {
|
|
8531
|
+
message: "Provide nodeKey or url.",
|
|
8532
|
+
path: ["nodeKey"]
|
|
8533
|
+
}).refine((value) => !(value.nodeKey && value.url), {
|
|
8534
|
+
message: "Provide nodeKey or url, not both.",
|
|
8535
|
+
path: ["nodeKey"]
|
|
8536
|
+
});
|
|
8537
|
+
var SITE_HEALTH_MCP_MAX_NODES = 25;
|
|
8538
|
+
var SITE_HEALTH_MCP_MAX_EDGES = 50;
|
|
8539
|
+
var siteHealthSubgraphInputSchema = z3.object({
|
|
8540
|
+
project: projectNameSchema,
|
|
8541
|
+
runId: runIdSchema.optional().describe("Historical crawl-bearing site-audit run ID. Omit for the latest complete crawl."),
|
|
8542
|
+
nodeKey: z3.string().min(1).optional().describe("Focus crawl node key. Omit with url to focus the crawl root."),
|
|
8543
|
+
url: z3.string().url().optional().describe("Focus canonical URL. Omit with nodeKey to focus the crawl root."),
|
|
8544
|
+
hops: z3.number().int().min(0).max(3).optional().describe("Neighborhood depth from the focus node. Keep this small."),
|
|
8545
|
+
maxNodes: z3.number().int().positive().max(SITE_HEALTH_MCP_MAX_NODES).default(SITE_HEALTH_MCP_MAX_NODES).describe("Hard MCP cap: at most 25 nodes. Narrow or refocus instead of loading the site."),
|
|
8546
|
+
maxEdges: z3.number().int().positive().max(SITE_HEALTH_MCP_MAX_EDGES).default(SITE_HEALTH_MCP_MAX_EDGES).describe("Hard MCP cap: at most 50 edges. Narrow or refocus instead of loading the site.")
|
|
8547
|
+
}).refine((value) => !(value.nodeKey && value.url), {
|
|
8548
|
+
message: "Provide nodeKey or url, not both.",
|
|
8549
|
+
path: ["nodeKey"]
|
|
8550
|
+
});
|
|
8551
|
+
var siteHealthPathInputSchema = z3.object({
|
|
8552
|
+
project: projectNameSchema,
|
|
8553
|
+
runId: runIdSchema.optional().describe("Historical crawl-bearing site-audit run ID. Omit for the latest complete crawl."),
|
|
8554
|
+
fromNodeKey: z3.string().min(1).optional().describe("Origin node key. Omit with fromUrl to start at the crawl root."),
|
|
8555
|
+
fromUrl: z3.string().url().optional().describe("Origin URL. Omit with fromNodeKey to start at the crawl root."),
|
|
8556
|
+
toNodeKey: z3.string().min(1).optional().describe("Required destination node key."),
|
|
8557
|
+
toUrl: z3.string().url().optional().describe("Required destination URL."),
|
|
8558
|
+
maxDepth: z3.number().int().positive().max(24).optional().describe("Maximum directed-link depth to search.")
|
|
8559
|
+
}).refine((value) => !(value.fromNodeKey && value.fromUrl), {
|
|
8560
|
+
message: "Provide fromNodeKey or fromUrl, not both.",
|
|
8561
|
+
path: ["fromNodeKey"]
|
|
8562
|
+
}).refine((value) => Boolean(value.toNodeKey || value.toUrl), {
|
|
8563
|
+
message: "Provide toNodeKey or toUrl.",
|
|
8564
|
+
path: ["toNodeKey"]
|
|
8565
|
+
}).refine((value) => !(value.toNodeKey && value.toUrl), {
|
|
8566
|
+
message: "Provide toNodeKey or toUrl, not both.",
|
|
8567
|
+
path: ["toNodeKey"]
|
|
8568
|
+
});
|
|
8569
|
+
var siteHealthChangesInputSchema = z3.object({
|
|
8570
|
+
project: projectNameSchema,
|
|
8571
|
+
fromRunId: runIdSchema.optional().describe("Earlier complete crawl run ID. Omit to compare the previous complete crawl."),
|
|
8572
|
+
toRunId: runIdSchema.optional().describe("Later complete crawl run ID. Omit to compare the latest complete crawl."),
|
|
8573
|
+
scope: z3.enum(["all", "pages", "links"]).optional().describe("Limit the diff to page or link changes. Omit or use all for both."),
|
|
8574
|
+
change: z3.enum(["all", "added", "removed", "changed"]).optional().describe("Limit the diff to one change kind. Omit or use all for every kind."),
|
|
8575
|
+
cursor: z3.string().min(1).optional().describe("Opaque cursor from the previous Site Health changes result."),
|
|
8576
|
+
limit: z3.number().int().positive().max(25).default(25).describe("Hard MCP cap: 25 records, because each change carries before and after DTOs.")
|
|
8577
|
+
});
|
|
8378
8578
|
var technicalAeoCrawlPagesInputSchema = z3.object({
|
|
8379
8579
|
project: projectNameSchema,
|
|
8380
8580
|
runId: runIdSchema.optional(),
|
|
@@ -10234,6 +10434,86 @@ var canonryMcpTools = [
|
|
|
10234
10434
|
openApiOperations: ["POST /api/v1/projects/{name}/discover/sessions/{id}/promote"],
|
|
10235
10435
|
handler: (client2, input) => client2.promoteDiscovery(input.project, input.sessionId, input.request)
|
|
10236
10436
|
}),
|
|
10437
|
+
defineTool({
|
|
10438
|
+
name: "canonry_site_health_overview",
|
|
10439
|
+
title: "Get Site Health overview",
|
|
10440
|
+
description: "Start a Site Health investigation with the latest or selected scan summary: root URL, completeness, crawl and link counts, budgets, versions, termination, and dead-link check state. Follow with a focused Site Health subgraph, shortest path, or scan changes; never request the interactive graph projection through MCP.",
|
|
10441
|
+
access: "read",
|
|
10442
|
+
tier: "monitoring",
|
|
10443
|
+
inputSchema: technicalAeoCrawlInputSchema,
|
|
10444
|
+
annotations: readAnnotations(),
|
|
10445
|
+
openApiOperations: ["GET /api/v1/projects/{name}/technical-aeo/crawl"],
|
|
10446
|
+
handler: (client2, input) => client2.getTechnicalAeoCrawl(input.project, { runId: input.runId })
|
|
10447
|
+
}),
|
|
10448
|
+
defineTool({
|
|
10449
|
+
name: "canonry_site_health_page_audit",
|
|
10450
|
+
title: "Get Site Health page audit",
|
|
10451
|
+
description: "Connect one graph page's audit score to its exact persisted evidence: factor scores, stable finding codes and messages, recommendations, and critical defects. The response includes crawl provenance and explicit no-crawl, details-unavailable, not-found, not-audited, ready/scores-only states. Use nodeKey from a Site Health page or subgraph read when possible. Link score remains an importance signal, not an audit finding.",
|
|
10452
|
+
access: "read",
|
|
10453
|
+
tier: "monitoring",
|
|
10454
|
+
inputSchema: siteHealthPageAuditInputSchema,
|
|
10455
|
+
annotations: readAnnotations(),
|
|
10456
|
+
openApiOperations: ["GET /api/v1/projects/{name}/technical-aeo/crawl/pages/audit"],
|
|
10457
|
+
handler: (client2, input) => client2.getTechnicalAeoPageAudit(input.project, {
|
|
10458
|
+
runId: input.runId,
|
|
10459
|
+
nodeKey: input.nodeKey,
|
|
10460
|
+
url: input.url
|
|
10461
|
+
})
|
|
10462
|
+
}),
|
|
10463
|
+
defineTool({
|
|
10464
|
+
name: "canonry_site_health_subgraph",
|
|
10465
|
+
title: "Inspect focused Site Health subgraph",
|
|
10466
|
+
description: "Read a compact canonical neighborhood around one page or the crawl root. Defaults to 25 nodes and 50 edges; expand hops or refocus only when needed. `countAccuracy=lower-bound` means traversal reached a cap, and `complete`/`termination` qualify partial-crawl results. This intentionally omits visualization coordinates and never materializes the full site graph.",
|
|
10467
|
+
access: "read",
|
|
10468
|
+
tier: "monitoring",
|
|
10469
|
+
inputSchema: siteHealthSubgraphInputSchema,
|
|
10470
|
+
annotations: readAnnotations(),
|
|
10471
|
+
openApiOperations: ["GET /api/v1/projects/{name}/technical-aeo/subgraph"],
|
|
10472
|
+
handler: (client2, input) => client2.getSiteHealthSubgraph(input.project, {
|
|
10473
|
+
runId: input.runId,
|
|
10474
|
+
nodeKey: input.nodeKey,
|
|
10475
|
+
url: input.url,
|
|
10476
|
+
hops: input.hops,
|
|
10477
|
+
maxNodes: input.maxNodes,
|
|
10478
|
+
maxEdges: input.maxEdges
|
|
10479
|
+
})
|
|
10480
|
+
}),
|
|
10481
|
+
defineTool({
|
|
10482
|
+
name: "canonry_site_health_path",
|
|
10483
|
+
title: "Find shortest Site Health path",
|
|
10484
|
+
description: "Find the shortest directed path of followable internal links from the crawl root or a selected page to one required destination. Use `complete` and `termination` to qualify unreachable or truncated outcomes from a partial crawl; it returns one path, not a graph traversal.",
|
|
10485
|
+
access: "read",
|
|
10486
|
+
tier: "monitoring",
|
|
10487
|
+
inputSchema: siteHealthPathInputSchema,
|
|
10488
|
+
annotations: readAnnotations(),
|
|
10489
|
+
openApiOperations: ["GET /api/v1/projects/{name}/technical-aeo/path"],
|
|
10490
|
+
handler: (client2, input) => client2.getSiteHealthPath(input.project, {
|
|
10491
|
+
runId: input.runId,
|
|
10492
|
+
fromNodeKey: input.fromNodeKey,
|
|
10493
|
+
fromUrl: input.fromUrl,
|
|
10494
|
+
toNodeKey: input.toNodeKey,
|
|
10495
|
+
toUrl: input.toUrl,
|
|
10496
|
+
maxDepth: input.maxDepth
|
|
10497
|
+
})
|
|
10498
|
+
}),
|
|
10499
|
+
defineTool({
|
|
10500
|
+
name: "canonry_site_health_changes",
|
|
10501
|
+
title: "Compare Site Health scans",
|
|
10502
|
+
description: "Compare two immutable complete scans (or the latest pair) for added, removed, and changed canonical pages or links. Results echo resolved filters and scan IDs; the first page has an exact summary, while continuations omit summary/total. MCP pages cap at 25 because every change carries before/after DTOs; filter before paging.",
|
|
10503
|
+
access: "read",
|
|
10504
|
+
tier: "monitoring",
|
|
10505
|
+
inputSchema: siteHealthChangesInputSchema,
|
|
10506
|
+
annotations: readAnnotations(),
|
|
10507
|
+
openApiOperations: ["GET /api/v1/projects/{name}/technical-aeo/changes"],
|
|
10508
|
+
handler: (client2, input) => client2.getSiteHealthChanges(input.project, {
|
|
10509
|
+
fromRunId: input.fromRunId,
|
|
10510
|
+
toRunId: input.toRunId,
|
|
10511
|
+
scope: input.scope,
|
|
10512
|
+
change: input.change,
|
|
10513
|
+
cursor: input.cursor,
|
|
10514
|
+
limit: input.limit
|
|
10515
|
+
})
|
|
10516
|
+
}),
|
|
10237
10517
|
defineTool({
|
|
10238
10518
|
name: "canonry_technical_aeo_score",
|
|
10239
10519
|
title: "Get Technical AEO score",
|