@canonry/canonry 5.19.0 → 5.19.1
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/aero/SKILL.md +13 -8
- package/assets/agent-workspace/skills/aero/references/portfolio-analysis.md +27 -10
- package/assets/agent-workspace/skills/canonry/references/canonry-cli.md +4 -1
- package/assets/assets/{AuditHistoryPanel-C_p8jX7Q.js → AuditHistoryPanel-ddq5tdlB.js} +1 -1
- package/assets/assets/{BacklinksPage-jD4nOGw1.js → BacklinksPage-g57_xzTX.js} +1 -1
- package/assets/assets/{HistoryPage-DJGBbtBY.js → HistoryPage-C-TdCUQ2.js} +1 -1
- package/assets/assets/{MeasurementPropertyPage-Dmr3TVlo.js → MeasurementPropertyPage-CAADmNfw.js} +1 -1
- package/assets/assets/{ProjectPage-B_haCKiA.js → ProjectPage-CoBwpHmA.js} +1 -1
- package/assets/assets/{RunRow-BMbwR2yk.js → RunRow-BpG0Zy-x.js} +1 -1
- package/assets/assets/{RunsPage-D8hHakq2.js → RunsPage-DK3pb1LH.js} +1 -1
- package/assets/assets/{SettingsPage-QKnRcFA9.js → SettingsPage-BruiY8Zh.js} +1 -1
- package/assets/assets/{SiteHealthSection-CDkUXqmb.js → SiteHealthSection-De4U11Gv.js} +3 -3
- package/assets/assets/{TrafficPage-CMif8RlM.js → TrafficPage-BVolLXT2.js} +1 -1
- package/assets/assets/{TrafficSourceDetailPage-DOCTP_4-.js → TrafficSourceDetailPage-CFDb6lPD.js} +1 -1
- package/assets/assets/{extract-error-message-Dm8RvYE5.js → extract-error-message-Bk1RTjzo.js} +1 -1
- package/assets/assets/{index-lj0fuFl4.js → index-B--AA1mG.js} +44 -44
- package/assets/assets/{react-sigma_core.esm.min-DOPuwLtN.js → react-sigma_core.esm.min--QXVK1JS.js} +1 -1
- package/assets/assets/{v2-overview-adapter-C19tUcDS.js → v2-overview-adapter-CpjJPZsC.js} +1 -1
- package/assets/index.html +1 -1
- package/dist/{chunk-P2EFPLIO.js → chunk-3IAIW5KH.js} +530 -132
- package/dist/{chunk-YHKKCXGY.js → chunk-4WROKFN6.js} +24 -8
- package/dist/{chunk-SPCEXW3B.js → chunk-EJXDABGU.js} +9 -3
- package/dist/{chunk-GUJY3RIM.js → chunk-EJZFTNZG.js} +439 -180
- package/dist/{chunk-ABUO27BV.js → chunk-J3JXJIST.js} +3 -3
- package/dist/{chunk-QJWIOCEO.js → chunk-PGOID3LE.js} +2 -2
- package/dist/{chunk-WLL7Q7JD.js → chunk-SOCYTKTF.js} +195 -23
- package/dist/cli.js +72 -16
- package/dist/{demo-server-BOIBS74F.js → demo-server-BLDYKCFS.js} +4 -4
- package/dist/index.js +6 -6
- package/dist/{intelligence-service-IWR2H6OW.js → intelligence-service-3MHYLKMS.js} +2 -2
- package/dist/mcp.js +4 -4
- package/package.json +11 -11
|
@@ -105,7 +105,7 @@ import {
|
|
|
105
105
|
trafficEventKindSchema,
|
|
106
106
|
trafficSeriesGranularitySchema,
|
|
107
107
|
visibilityReportRequestSchema
|
|
108
|
-
} from "./chunk-
|
|
108
|
+
} from "./chunk-SOCYTKTF.js";
|
|
109
109
|
|
|
110
110
|
// src/cli-error.ts
|
|
111
111
|
function isMachineFormat(format) {
|
|
@@ -398,7 +398,12 @@ var measurementPropertyEvidenceInputSchema = measurementPropertyEvidenceQuerySch
|
|
|
398
398
|
)
|
|
399
399
|
}).strict();
|
|
400
400
|
var measurementPortfolioSummaryInputSchema = measurementPortfolioSummaryQuerySchema.extend({
|
|
401
|
-
project: projectNameSchema
|
|
401
|
+
project: projectNameSchema,
|
|
402
|
+
groupKey: measurementPortfolioSummaryQuerySchema.shape.groupKey.describe("A market stable key (a row's metro.groupKey). Scopes rows to that market and lists its direct submarkets."),
|
|
403
|
+
// Capped below the route's 50: past about 10 rows the per-row evidence
|
|
404
|
+
// (names given instead, cited domains) no longer fits the tool-result cap.
|
|
405
|
+
limit: z3.number().int().positive().max(10).optional().describe("Rows per list, at most 10. Default 4 keeps the whole result under the tool-result cap; prefer groupKey over a larger limit."),
|
|
406
|
+
includeNestedMarkets: measurementPortfolioSummaryQuerySchema.shape.includeNestedMarkets.describe("Every market at every level, uncapped. Off by default; large portfolios exceed the cap with it on.")
|
|
402
407
|
}).strict();
|
|
403
408
|
var measurementPropertyQuestionsInputSchema = measurementPropertyQuestionsQuerySchema.extend({
|
|
404
409
|
project: projectNameSchema
|
|
@@ -1279,22 +1284,33 @@ var canonryMcpTools = [
|
|
|
1279
1284
|
defineTool({
|
|
1280
1285
|
name: "canonry_analytics_sources",
|
|
1281
1286
|
title: "Get cited-source rankings",
|
|
1282
|
-
description: "Where AI engines
|
|
1287
|
+
description: "Where AI engines cite from for a project: cited domains ranked by how many answers cite them, each tagged with a category and a surface class (own / direct-competitor / ota-aggregator / editorial-media / other), plus a surface-class roll-up and a per-provider breakdown. Project-wide: without `runId` it pools every sweep in the window (`runCount` says how many); without `queryClass` it pools branded and non-brand answers, where branded queries inflate your own domain. For the sources behind non-brand answers, set `queryClass=non-brand` and the latest `runId`; on a v2 measurement plan the class comes from the plan, the same answers as canonry_competitor_landscape with scope=all-markets. Counts come from each answer's stored source list, so every engine is included, Gemini too. A domain counts at most once per answer; `answerShare` is the share of all answers in scope that cite it. `providersWithoutSources` names engines that answered but cited nothing. `limit` caps each ranked list (default 10 for this tool, which keeps each engine list whole); a long-tail rollup keeps the totals. The per-query breakdown is omitted unless `includeByQuery` is true. No LLM calls; probe runs excluded.",
|
|
1283
1288
|
access: "read",
|
|
1284
1289
|
tier: "monitoring",
|
|
1285
1290
|
inputSchema: z3.object({
|
|
1286
1291
|
project: projectNameSchema,
|
|
1287
1292
|
window: analyticsWindowSchema.optional().describe("Time range: 7d, 30d, 90d, or all (default all)."),
|
|
1288
|
-
limit: z3.number().int().positive().optional().describe("Cap each ranked list to the top N domains.
|
|
1293
|
+
limit: z3.number().int().positive().max(50).optional().describe("Cap each ranked list to the top N domains. Default 10; larger lists can exceed the tool-result cap."),
|
|
1294
|
+
runId: z3.string().trim().min(1).optional().describe("Read one answer-visibility run (for example the latest sweep) instead of pooling every run in the window."),
|
|
1295
|
+
queryClass: z3.enum(["all", "branded", "non-brand"]).optional().describe("Branded or non-brand answers only. With an active v2 measurement plan the class comes from the plan assignments. Default all pools both classes."),
|
|
1296
|
+
includeByQuery: z3.boolean().optional().describe("Include the per-query breakdown. It is large; default false for this tool.")
|
|
1289
1297
|
}),
|
|
1290
1298
|
annotations: readAnnotations(),
|
|
1291
1299
|
openApiOperations: ["GET /api/v1/projects/{name}/analytics/sources"],
|
|
1292
|
-
handler: (client, input) => client.getAnalyticsSources(input.project, {
|
|
1300
|
+
handler: (client, input) => client.getAnalyticsSources(input.project, {
|
|
1301
|
+
window: input.window,
|
|
1302
|
+
// The full ranked lists run past the agent's tool-result cap on a large
|
|
1303
|
+
// project, and the per-engine lists are the first thing lost.
|
|
1304
|
+
limit: input.limit ?? 10,
|
|
1305
|
+
runId: input.runId,
|
|
1306
|
+
queryClass: input.queryClass,
|
|
1307
|
+
includeByQuery: input.includeByQuery ?? false
|
|
1308
|
+
})
|
|
1293
1309
|
}),
|
|
1294
1310
|
defineTool({
|
|
1295
1311
|
name: "canonry_competitor_landscape",
|
|
1296
1312
|
title: "Get historical competitor landscape",
|
|
1297
|
-
description: "Returns pinned competitors first, then observed direct competitors and other cited sources from stored answer/source evidence only. Mention share is percentage points (0..100) from answer text; citations are independent. The response carries basis (tracked or observed), availability, and reason. Pins exclusively define the comparison set when present. Otherwise at least 3 stored direct competitors must each be mentioned in 3 answers in the selected scope; raw names and platforms never enter that denominator. Without a comparison set the ratio is null, never 100%. The full comparison array is uncapped. Share of voice needs ONE query class: `queryClass=all`, and omitting it, pool branded and non-brand, so every `shareOfVoice` comes back null and only the counts are published. Pass `queryClass=non-brand` (or `branded`) for a ratio, exactly as visibility-stats does. A project with no brand name or alias cannot be split by class, so a class-scoped read on one is refused rather than answered empty. Optional groupBy: model adds provider/requested-model groups with separate served-model evidence and sample counts. Optional model filters one exact requested model ID and requires provider. Unknown historical models remain explicit. Groups are not a matched-query or equal-weight comparison. Advanced reads support one market group or explicit scope: all-markets. No provider, discovery, or classifier work runs. Ranked lists are capped at 100 observed/other-source rows per group; pins remain complete. Model groups are capped at 50 and disclose truncation.",
|
|
1313
|
+
description: "Returns pinned competitors first, then observed direct competitors and other cited sources from stored answer/source evidence only. Mention share is percentage points (0..100) from answer text; citations are independent. The response carries basis (tracked or observed), availability, and reason. Pins exclusively define the comparison set when present. Otherwise at least 3 stored direct competitors must each be mentioned in 3 answers in the selected scope; raw names and platforms never enter that denominator. Without a comparison set the ratio is null, never 100%. The full comparison array is uncapped. Share of voice needs ONE query class: `queryClass=all`, and omitting it, pool branded and non-brand, so every `shareOfVoice` comes back null and only the counts are published. Pass `queryClass=non-brand` (or `branded`) for a ratio, exactly as visibility-stats does. A project with no brand name or alias cannot be split by class, so a class-scoped read on one is refused rather than answered empty. Optional groupBy: model adds provider/requested-model groups with separate served-model evidence and sample counts. Optional model filters one exact requested model ID and requires provider. Unknown historical models remain explicit. Groups are not a matched-query or equal-weight comparison. Advanced reads support one market group or explicit scope: all-markets. On a project with an active v2 measurement plan, queryClass=branded or non-brand with no scope or groupKey defaults to scope=all-markets, so classes come from the plan; pass scope=project to force the text classifier. No provider, discovery, or classifier work runs. Ranked lists are capped at 100 observed/other-source rows per group; pins remain complete. `observedNames` are names written in answer text, not cited sources, capped at the top 50 by answer count; `observedNamesTotal` is the full count. Model groups are capped at 50 and disclose truncation.",
|
|
1298
1314
|
access: "read",
|
|
1299
1315
|
tier: "monitoring",
|
|
1300
1316
|
inputSchema: competitorLandscapeInputSchema,
|
|
@@ -2438,7 +2454,7 @@ var canonryMcpTools = [
|
|
|
2438
2454
|
defineTool({
|
|
2439
2455
|
name: "canonry_measurement_plan_get",
|
|
2440
2456
|
title: "Get measurement plan",
|
|
2441
|
-
description: "Get the active measurement plan for a project.",
|
|
2457
|
+
description: "Get the active measurement plan for a project: plan structure only (targets, groups, query assignments), no metrics. It can be very large on a big portfolio; for analysis prefer canonry_measurement_portfolio_summary and canonry_measurement_overview.",
|
|
2442
2458
|
access: "read",
|
|
2443
2459
|
tier: "setup",
|
|
2444
2460
|
inputSchema: projectInputSchema,
|
|
@@ -2557,7 +2573,7 @@ var canonryMcpTools = [
|
|
|
2557
2573
|
defineTool({
|
|
2558
2574
|
name: "canonry_measurement_portfolio_summary",
|
|
2559
2575
|
title: "Summarize measured Properties",
|
|
2560
|
-
description: "Start here for best
|
|
2576
|
+
description: "Start here for best and worst Properties. One call returns the weakest Properties, the names answers wrote instead of them, and the domains engines cited for them. Defaults to non-brand queries; state the returned queryClass and never pool branded with non-brand. Keep the default limit; for more rows narrow with groupKey (a metro) rather than raising limit, which can overflow the tool-result cap. Mention (answer text names the Property) and citation (a source URL on its page) are separate: report each as numerator/denominator, with any unattributed count beside mention. Denominators count answers, one per query per engine (queries x engines = answers). Group Properties only by each row's metro and submarkets, never by label. namedInsteadInAnswerText lists names written in the answer text of answers that neither named nor cited the Property, counted by answer: they are not citations. citedDomains and weakestAnswerSources count answers citing each domain, every engine included; weakestAnswerSources covers the weakest rows plus every tied Property, each answer once. When tiedAtWeakest is set, that many Properties share the weakest rates and are ordered by name, not ranked. mentionRanking.strongest/.weakest rank every Property with an available mention rate; .excluded lists the rest with reasons. markets lists one level worst-first (metros, or a groupKey's submarkets), capped at limit, with totalMarkets; includeNestedMarkets returns every level. Markets may share Properties and never sum to portfolio totals. Reads stored data only; never starts provider work.",
|
|
2561
2577
|
access: "read",
|
|
2562
2578
|
tier: "monitoring",
|
|
2563
2579
|
inputSchema: measurementPortfolioSummaryInputSchema,
|
|
@@ -5,7 +5,7 @@ import {
|
|
|
5
5
|
PACKAGE_VERSION,
|
|
6
6
|
canonryMcpTools,
|
|
7
7
|
isMachineFormat
|
|
8
|
-
} from "./chunk-
|
|
8
|
+
} from "./chunk-4WROKFN6.js";
|
|
9
9
|
import {
|
|
10
10
|
AGENT_PROVIDER_IDS,
|
|
11
11
|
CANONRY_NPM_PACKAGE_URL,
|
|
@@ -36,7 +36,7 @@ import {
|
|
|
36
36
|
skillsClientSchema,
|
|
37
37
|
upgradeCaveatFor,
|
|
38
38
|
upgradeCommandFor
|
|
39
|
-
} from "./chunk-
|
|
39
|
+
} from "./chunk-SOCYTKTF.js";
|
|
40
40
|
|
|
41
41
|
// src/config.ts
|
|
42
42
|
import fs from "fs";
|
|
@@ -7082,7 +7082,13 @@ var ApiClient = class {
|
|
|
7082
7082
|
() => getApiV1ProjectsByNameAnalyticsSources({
|
|
7083
7083
|
client: this.heyClient,
|
|
7084
7084
|
path: { name: project },
|
|
7085
|
-
query: {
|
|
7085
|
+
query: {
|
|
7086
|
+
window: opts.window,
|
|
7087
|
+
limit: opts.limit,
|
|
7088
|
+
runId: opts.runId,
|
|
7089
|
+
queryClass: opts.queryClass,
|
|
7090
|
+
...opts.includeByQuery === void 0 ? {} : { includeByQuery: opts.includeByQuery ? "true" : "false" }
|
|
7091
|
+
}
|
|
7086
7092
|
})
|
|
7087
7093
|
);
|
|
7088
7094
|
}
|