@canonry/canonry 4.172.1 → 4.172.3

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.
Files changed (31) hide show
  1. package/assets/agent-workspace/skills/aero/references/reporting.md +8 -4
  2. package/assets/agent-workspace/skills/canonry/references/aeo-analysis.md +1 -1
  3. package/assets/agent-workspace/skills/canonry/references/canonry-cli.md +4 -3
  4. package/assets/assets/{AuditHistoryPanel-BO_TSFPx.js → AuditHistoryPanel-DF8utxHN.js} +1 -1
  5. package/assets/assets/{BacklinksPage-CNrzKbiR.js → BacklinksPage-Hz5fjTP-.js} +1 -1
  6. package/assets/assets/{HistoryPage-CvzLzfj3.js → HistoryPage-EeNWcnRk.js} +1 -1
  7. package/assets/assets/{MeasurementPropertyPage-CUdAqft3.js → MeasurementPropertyPage-CWvVMiIo.js} +1 -1
  8. package/assets/assets/ProjectPage-CBVwd4DJ.js +9 -0
  9. package/assets/assets/{RunRow-BLZsQTiY.js → RunRow-CLwmqMWg.js} +1 -1
  10. package/assets/assets/{RunsPage-CTuTDUcn.js → RunsPage-Cxc9xDm9.js} +1 -1
  11. package/assets/assets/{SettingsPage-BY-nM5uj.js → SettingsPage-gg7QM6am.js} +1 -1
  12. package/assets/assets/{SiteHealthSection-br9-ha8G.js → SiteHealthSection-DhpNThBa.js} +3 -3
  13. package/assets/assets/{TrafficPage-BgX1QlXy.js → TrafficPage-BkDwv0uO.js} +1 -1
  14. package/assets/assets/{TrafficSourceDetailPage-D5bsBc6A.js → TrafficSourceDetailPage-gyh7Kxb3.js} +1 -1
  15. package/assets/assets/{extract-error-message-BywQFP69.js → extract-error-message-DVQ46FzX.js} +1 -1
  16. package/assets/assets/{index-BpHZirJJ.js → index-ClNW_gZV.js} +27 -27
  17. package/assets/assets/index-D1mXm81Z.css +1 -0
  18. package/assets/assets/{react-sigma_core.esm.min-Do4rkEBs.js → react-sigma_core.esm.min-BhFLGF9e.js} +1 -1
  19. package/assets/index.html +2 -2
  20. package/dist/{chunk-5MRE2TXR.js → chunk-BZDNTUCZ.js} +8 -5
  21. package/dist/{chunk-IAX4WRAR.js → chunk-OHSUOEVB.js} +4 -4
  22. package/dist/{chunk-7L4453BU.js → chunk-WFVK3XC7.js} +2 -2
  23. package/dist/{chunk-X63CLHYM.js → chunk-WGN2VT7L.js} +4797 -4680
  24. package/dist/{chunk-3XN226N6.js → chunk-XEWBDO5L.js} +767 -247
  25. package/dist/cli.js +71 -14
  26. package/dist/index.js +4 -4
  27. package/dist/{intelligence-service-FSHZXSGK.js → intelligence-service-PPYG6NJP.js} +2 -2
  28. package/dist/mcp.js +3 -3
  29. package/package.json +11 -11
  30. package/assets/assets/ProjectPage-xbRWsne7.js +0 -9
  31. package/assets/assets/index-BsQGKWA6.css +0 -1
package/dist/cli.js CHANGED
@@ -26,11 +26,11 @@ import {
26
26
  showFirstRunNotice,
27
27
  trackCliCommandFinished,
28
28
  trackEvent
29
- } from "./chunk-IAX4WRAR.js";
29
+ } from "./chunk-OHSUOEVB.js";
30
30
  import {
31
31
  autoSyncSkills,
32
32
  formatAutoSyncNotice
33
- } from "./chunk-7L4453BU.js";
33
+ } from "./chunk-WFVK3XC7.js";
34
34
  import {
35
35
  CliError,
36
36
  EXIT_SYSTEM_ERROR,
@@ -55,7 +55,7 @@ import {
55
55
  saveConfigPatch,
56
56
  systemError,
57
57
  usageError
58
- } from "./chunk-5MRE2TXR.js";
58
+ } from "./chunk-BZDNTUCZ.js";
59
59
  import {
60
60
  CLOUDFLARE_WORKER_BINDINGS,
61
61
  CLOUDFLARE_WORKER_GENERATED_MARKER,
@@ -69,7 +69,7 @@ import {
69
69
  projects,
70
70
  queries,
71
71
  renderReportHtml
72
- } from "./chunk-3XN226N6.js";
72
+ } from "./chunk-XEWBDO5L.js";
73
73
  import {
74
74
  AdsDeliverySnapshotStatuses,
75
75
  AdsHistoricalCampaignRollupStatuses,
@@ -137,7 +137,7 @@ import {
137
137
  providerQuotaPolicySchema,
138
138
  resolveProviderInput,
139
139
  winnabilityClassSchema
140
- } from "./chunk-X63CLHYM.js";
140
+ } from "./chunk-WGN2VT7L.js";
141
141
 
142
142
  // src/cli.ts
143
143
  import { pathToFileURL } from "url";
@@ -7792,6 +7792,41 @@ async function googlePerformanceDaily(project, opts) {
7792
7792
  Trend (least-squares fit over ${days} day${days === 1 ? "" : "s"}):`);
7793
7793
  for (const line of trendLines) console.log(line);
7794
7794
  }
7795
+ const cmp = data.periodComparison;
7796
+ if (cmp && !cmp.comparable) {
7797
+ console.log(
7798
+ `
7799
+ No period comparison: period comparison needs property-level daily data. Sync again, or pick a range covered by property totals.`
7800
+ );
7801
+ } else if (cmp) {
7802
+ const pct4 = (ratio, prior, trailing, inverted) => {
7803
+ if (ratio === null) {
7804
+ if (prior !== null && trailing !== null && prior <= 0 && trailing > 0) {
7805
+ return `new in last ${cmp.days} day${cmp.days === 1 ? "" : "s"}`;
7806
+ }
7807
+ if (prior === null || prior <= 0) return "no prior period to compare";
7808
+ if (trailing === null) return `no value in last ${cmp.days} day${cmp.days === 1 ? "" : "s"}`;
7809
+ return "comparison unavailable";
7810
+ }
7811
+ if (ratio === 0) return "no change";
7812
+ const better = inverted ? ratio < 0 : ratio > 0;
7813
+ const magnitude = Math.abs(ratio * 100);
7814
+ const shown = magnitude < 0.1 ? "<0.1" : magnitude.toFixed(1);
7815
+ return `${ratio > 0 ? "+" : "-"}${shown}% ${better ? "better" : "worse"}`;
7816
+ };
7817
+ console.log(
7818
+ `
7819
+ Last ${cmp.days} day${cmp.days === 1 ? "" : "s"} (${cmp.trailing.startDate} to ${cmp.trailing.endDate}) vs prior ${cmp.days} (${cmp.prior.startDate} to ${cmp.prior.endDate}):`
7820
+ );
7821
+ for (const [label, ratio, prior, trailing, inverted] of [
7822
+ ["Clicks", cmp.change.clicks, cmp.prior.clicks, cmp.trailing.clicks, false],
7823
+ ["Impressions", cmp.change.impressions, cmp.prior.impressions, cmp.trailing.impressions, false],
7824
+ ["CTR", cmp.change.ctr, cmp.prior.ctr, cmp.trailing.ctr, false],
7825
+ ["Position", cmp.change.position, cmp.prior.position, cmp.trailing.position, true]
7826
+ ]) {
7827
+ console.log(` ${`${label}:`.padEnd(13)}${pct4(ratio, prior, trailing, inverted)}`);
7828
+ }
7829
+ }
7795
7830
  console.log();
7796
7831
  console.log(` ${"DATE".padEnd(12)}${"CLICKS".padStart(10)}${"IMPR".padStart(12)}${"CTR".padStart(10)}${"POS".padStart(9)}`);
7797
7832
  console.log(` ${"\u2500".repeat(12)}${"\u2500".repeat(10)}${"\u2500".repeat(12)}${"\u2500".repeat(10)}${"\u2500".repeat(9)}`);
@@ -13080,14 +13115,14 @@ async function showAllOverviews(opts) {
13080
13115
  console.log(`
13081
13116
  Overviews (${overviews.length} project${overviews.length === 1 ? "" : "s"}):
13082
13117
  `);
13083
- const cols = { project: 20, mention: 10, cited: 10, share: 18, queries: 10 };
13084
- console.log(` ${cell("Project", cols.project)}${cell("Mention", cols.mention)}${cell("Cited", cols.cited)}${cell("Share", cols.share)}${cell("Queries", cols.queries)}Latest run`);
13118
+ const cols = { project: 20, mention: 10, cited: 10, share: 42, queries: 10 };
13119
+ console.log(` ${cell("Project", cols.project)}${cell("Mention", cols.mention)}${cell("Cited", cols.cited)}${cell("Mention share \xB7 scope", cols.share)}${cell("Queries", cols.queries)}Latest run`);
13085
13120
  for (const ov of overviews) {
13086
13121
  const project = ov.project.displayName || ov.project.name;
13087
13122
  const queries2 = `${ov.queryCounts.citedQueries}/${ov.queryCounts.totalQueries}`;
13088
13123
  const latest = ov.latestRun.run?.finishedAt ?? ov.latestRun.run?.createdAt ?? "\u2014";
13089
13124
  console.log(
13090
- ` ${cell(project, cols.project)}${cell(ov.scores.mention.value, cols.mention)}${cell(ov.scores.visibility.value, cols.cited)}${cell(ov.scores.mentionShare.value, cols.share)}${cell(queries2, cols.queries)}${latest}`
13125
+ ` ${cell(project, cols.project)}${cell(ov.scores.mention.value, cols.mention)}${cell(ov.scores.visibility.value, cols.cited)}${cell(`${ov.scores.mentionShare.value} \xB7 ${ov.scores.mentionShare.scope} queries`, cols.share)}${cell(queries2, cols.queries)}${latest}`
13091
13126
  );
13092
13127
  }
13093
13128
  console.log();
@@ -16123,7 +16158,8 @@ async function showVisibilityStats(project, opts) {
16123
16158
  month: opts.month,
16124
16159
  lastRuns: opts.lastRuns,
16125
16160
  groupBy: opts.byProvider ? "provider" : void 0,
16126
- shareOfVoice: opts.shareOfVoice
16161
+ shareOfVoice: opts.shareOfVoice,
16162
+ queryClass: opts.queryClass
16127
16163
  });
16128
16164
  if (opts.format === "jsonl") {
16129
16165
  emitJsonl(data.queries.map((q) => ({ project: data.project, runCount: data.window.runCount, ...q })));
@@ -16149,6 +16185,9 @@ async function showVisibilityCompare(project, opts) {
16149
16185
  printVisibilityCompare(data);
16150
16186
  }
16151
16187
  function periodCell(p) {
16188
+ if (p.availability === "no-competitive-frame") {
16189
+ return `unavailable: no competitive frame (${p.numerator} observed)`;
16190
+ }
16152
16191
  if (p.point === null || p.ciLow === null || p.ciHigh === null) return "no data";
16153
16192
  const p1 = (v) => formatRatio(v);
16154
16193
  return `${p1(p.point)} [${p1(p.ciLow)}, ${p1(p.ciHigh)}]`;
@@ -16167,6 +16206,11 @@ function verdictCell(m) {
16167
16206
  return "model unknown";
16168
16207
  }
16169
16208
  }
16209
+ function metricQueryClassLabel(metric) {
16210
+ if (metric.queryClass === "non-brand") return "non-brand queries";
16211
+ if (metric.queryClass === "pooled") return "pooled queries; classification unavailable";
16212
+ return "all queries";
16213
+ }
16170
16214
  function printVisibilityCompare(data) {
16171
16215
  console.log(`AEO month over month: ${data.project} ${data.from.month} -> ${data.to.month}`);
16172
16216
  const b = data.basket;
@@ -16183,7 +16227,7 @@ function printVisibilityCompare(data) {
16183
16227
  }
16184
16228
  console.log("");
16185
16229
  const rows = data.metrics.map((m) => ({
16186
- label: `${m.label}${m.driftRobust ? " *" : ""}`,
16230
+ label: `${m.label} \xB7 ${metricQueryClassLabel(m)}${m.driftRobust ? " *" : ""}`,
16187
16231
  to: periodCell(m.to),
16188
16232
  from: periodCell(m.from),
16189
16233
  verdict: verdictCell(m)
@@ -16289,10 +16333,14 @@ function printVisibilityStats(data) {
16289
16333
  const sov = data.shareOfVoice;
16290
16334
  if (sov) {
16291
16335
  console.log("");
16292
- const pctStr = sov.percent === null ? "\u2014 (no competitors configured)" : `${sov.percent}%`;
16336
+ const pctStr = sov.percent !== null ? `${sov.percent}%` : sov.competitorCount === 0 ? "\u2014 (no competitors configured)" : sov.snapshotsWithAnswerText === 0 ? "\u2014 (no answer text in scope)" : "\u2014 (no brands mentioned in scope)";
16337
+ const scope = sov.queryClass === "pooled" ? "pooled queries \xB7 classification unavailable" : `${sov.queryClass} queries`;
16293
16338
  console.log(
16294
- `Share of voice: ${pctStr} (you ${sov.projectMentions} vs competitors ${sov.competitorMentions} brand mentions across ${sov.snapshotsWithAnswerText} answers)`
16339
+ `Share of voice (${scope}): ${pctStr} (you ${sov.projectMentions} vs competitors ${sov.competitorMentions} brand mentions across ${sov.snapshotsWithAnswerText} answers)`
16295
16340
  );
16341
+ if (sov.queryClass === "non-brand") {
16342
+ console.log(" branded queries excluded on purpose \u2014 re-run with --query-class branded for brand recall");
16343
+ }
16296
16344
  for (const c of sov.perCompetitor.slice(0, 8)) {
16297
16345
  console.log(` ${c.domain}: ${c.mentions}`);
16298
16346
  }
@@ -16300,7 +16348,14 @@ function printVisibilityStats(data) {
16300
16348
  }
16301
16349
 
16302
16350
  // src/cli-commands/visibility-stats.ts
16303
- var USAGE5 = "canonry visibility-stats <project> [--since <iso>] [--until <iso>] [--month <YYYY-MM>] [--last-runs <n>] [--by-provider] [--share-of-voice] [--format json|jsonl]";
16351
+ var USAGE5 = "canonry visibility-stats <project> [--since <iso>] [--until <iso>] [--month <YYYY-MM>] [--last-runs <n>] [--by-provider] [--share-of-voice] [--query-class branded|non-brand] [--format json|jsonl]";
16352
+ function parseQueryClass(value) {
16353
+ if (value === void 0 || value === "") return void 0;
16354
+ if (value !== "branded" && value !== "non-brand") {
16355
+ throw new Error(`--query-class must be "branded" or "non-brand" (got "${value}")`);
16356
+ }
16357
+ return value;
16358
+ }
16304
16359
  var COMPARE_USAGE = "canonry visibility-compare <project> --from <YYYY-MM> --to <YYYY-MM> [--format json]";
16305
16360
  var VISIBILITY_STATS_CLI_COMMANDS = [
16306
16361
  {
@@ -16312,7 +16367,8 @@ var VISIBILITY_STATS_CLI_COMMANDS = [
16312
16367
  month: stringOption(),
16313
16368
  "last-runs": stringOption(),
16314
16369
  "by-provider": { type: "boolean", default: false },
16315
- "share-of-voice": { type: "boolean", default: false }
16370
+ "share-of-voice": { type: "boolean", default: false },
16371
+ "query-class": stringOption()
16316
16372
  },
16317
16373
  run: async (input) => {
16318
16374
  const project = requireProject(input, "visibility-stats", USAGE5);
@@ -16327,6 +16383,7 @@ var VISIBILITY_STATS_CLI_COMMANDS = [
16327
16383
  }),
16328
16384
  byProvider: getBoolean(input.values, "by-provider"),
16329
16385
  shareOfVoice: getBoolean(input.values, "share-of-voice"),
16386
+ queryClass: parseQueryClass(getString(input.values, "query-class")),
16330
16387
  format: input.format
16331
16388
  });
16332
16389
  }
package/dist/index.js CHANGED
@@ -3,12 +3,12 @@ import {
3
3
  createGoogleMarketingCredentialStore,
4
4
  createGoogleMarketingRuntime,
5
5
  createServer
6
- } from "./chunk-IAX4WRAR.js";
6
+ } from "./chunk-OHSUOEVB.js";
7
7
  import {
8
8
  loadConfig
9
- } from "./chunk-5MRE2TXR.js";
10
- import "./chunk-3XN226N6.js";
11
- import "./chunk-X63CLHYM.js";
9
+ } from "./chunk-BZDNTUCZ.js";
10
+ import "./chunk-XEWBDO5L.js";
11
+ import "./chunk-WGN2VT7L.js";
12
12
  export {
13
13
  GoogleMarketingRuntimeError,
14
14
  createGoogleMarketingCredentialStore,
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  IntelligenceService
3
- } from "./chunk-3XN226N6.js";
4
- import "./chunk-X63CLHYM.js";
3
+ } from "./chunk-XEWBDO5L.js";
4
+ import "./chunk-WGN2VT7L.js";
5
5
  export {
6
6
  IntelligenceService
7
7
  };
package/dist/mcp.js CHANGED
@@ -1,15 +1,15 @@
1
1
  import {
2
2
  autoSyncSkills
3
- } from "./chunk-7L4453BU.js";
3
+ } from "./chunk-WFVK3XC7.js";
4
4
  import {
5
5
  CliError,
6
6
  PACKAGE_VERSION,
7
7
  canonryMcpTools,
8
8
  createApiClient
9
- } from "./chunk-5MRE2TXR.js";
9
+ } from "./chunk-BZDNTUCZ.js";
10
10
  import {
11
11
  isReadOnlyKey
12
- } from "./chunk-X63CLHYM.js";
12
+ } from "./chunk-WGN2VT7L.js";
13
13
 
14
14
  // src/mcp/cli.ts
15
15
  import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@canonry/canonry",
3
- "version": "4.172.1",
3
+ "version": "4.172.3",
4
4
  "type": "module",
5
5
  "description": "Agent-first open-source AEO operating platform - track how answer engines cite your domain",
6
6
  "license": "FSL-1.1-ALv2",
@@ -71,30 +71,30 @@
71
71
  "tsup": "^8.5.1",
72
72
  "tsx": "^4.19.0",
73
73
  "@ainyc/canonry-api-client": "0.0.0",
74
- "@ainyc/canonry-config": "0.0.0",
75
74
  "@ainyc/canonry-contracts": "0.0.0",
76
- "@ainyc/canonry-integration-bing": "0.0.0",
77
75
  "@ainyc/canonry-db": "0.0.0",
76
+ "@ainyc/canonry-integration-bing": "0.0.0",
78
77
  "@ainyc/canonry-integration-cloudflare-queue": "0.0.0",
78
+ "@ainyc/canonry-api-routes": "0.0.0",
79
79
  "@ainyc/canonry-integration-cloudflare-worker": "0.0.0",
80
80
  "@ainyc/canonry-integration-openai-ads": "0.0.0",
81
- "@ainyc/canonry-api-routes": "0.0.0",
82
81
  "@ainyc/canonry-integration-cloud-run": "0.0.0",
83
- "@ainyc/canonry-integration-google-ads": "0.0.0",
82
+ "@ainyc/canonry-integration-google": "0.0.0",
84
83
  "@ainyc/canonry-integration-commoncrawl": "0.0.0",
85
- "@ainyc/canonry-integration-google-places": "0.0.0",
86
84
  "@ainyc/canonry-integration-google-business-profile": "0.0.0",
85
+ "@ainyc/canonry-integration-google-ads": "0.0.0",
86
+ "@ainyc/canonry-config": "0.0.0",
87
+ "@ainyc/canonry-integration-google-places": "0.0.0",
87
88
  "@ainyc/canonry-integration-google-tag-manager": "0.0.0",
89
+ "@ainyc/canonry-intelligence": "0.0.0",
88
90
  "@ainyc/canonry-integration-traffic": "0.0.0",
89
91
  "@ainyc/canonry-integration-wordpress": "0.0.0",
90
- "@ainyc/canonry-intelligence": "0.0.0",
91
92
  "@ainyc/canonry-provider-cdp": "0.0.0",
93
+ "@ainyc/canonry-provider-gemini": "0.0.0",
94
+ "@ainyc/canonry-provider-claude": "0.0.0",
92
95
  "@ainyc/canonry-provider-local": "0.0.0",
93
- "@ainyc/canonry-integration-google": "0.0.0",
94
96
  "@ainyc/canonry-provider-openai": "0.0.0",
95
- "@ainyc/canonry-provider-perplexity": "0.0.0",
96
- "@ainyc/canonry-provider-gemini": "0.0.0",
97
- "@ainyc/canonry-provider-claude": "0.0.0"
97
+ "@ainyc/canonry-provider-perplexity": "0.0.0"
98
98
  },
99
99
  "scripts": {
100
100
  "build": "tsx scripts/copy-agent-assets.ts && tsup && tsx build-web.ts",