@canonry/canonry 4.131.0 → 4.133.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.
Files changed (26) hide show
  1. package/assets/agent-workspace/skills/canonry/references/canonry-cli.md +7 -0
  2. package/assets/assets/{AuditHistoryPanel-yJXZMO5t.js → AuditHistoryPanel-CVDg3GXg.js} +1 -1
  3. package/assets/assets/{BacklinksPage-6VTLbAYx.js → BacklinksPage-Dh4RIvS7.js} +1 -1
  4. package/assets/assets/{ChartPrimitives-D5YGiDLi.js → ChartPrimitives-BK89G5H_.js} +1 -1
  5. package/assets/assets/{HistoryPage-BxdTM6-R.js → HistoryPage-D8rMu_Js.js} +1 -1
  6. package/assets/assets/{ProjectPage-BJKxZPRO.js → ProjectPage-CiTDveNK.js} +1 -1
  7. package/assets/assets/{RunRow-DTrAO7tE.js → RunRow-DVOwbmTp.js} +1 -1
  8. package/assets/assets/{RunsPage-CHU0DQGl.js → RunsPage-tz3Oil7N.js} +1 -1
  9. package/assets/assets/{SettingsPage-bOIwju6t.js → SettingsPage-C698YidM.js} +1 -1
  10. package/assets/assets/{TrafficPage-BKvuR482.js → TrafficPage-XDXWMtey.js} +1 -1
  11. package/assets/assets/{TrafficSourceDetailPage-3-iUTgQg.js → TrafficSourceDetailPage-Clz8kOR8.js} +1 -1
  12. package/assets/assets/{arrow-left-BXSfGhr6.js → arrow-left-GWLbh0pE.js} +1 -1
  13. package/assets/assets/{extract-error-message-DEAY62LS.js → extract-error-message-Dk8w-sb1.js} +1 -1
  14. package/assets/assets/index-jTshRRh0.js +210 -0
  15. package/assets/assets/{trash-2-O1wo9IX1.js → trash-2-DwnzsuH1.js} +1 -1
  16. package/assets/index.html +1 -1
  17. package/dist/{chunk-5GQ6FF5R.js → chunk-42P7POVS.js} +4 -4
  18. package/dist/{chunk-73HPY6XQ.js → chunk-P4MIG7V5.js} +81 -1
  19. package/dist/{chunk-ZXVWL5HX.js → chunk-VPY3PZXV.js} +1827 -873
  20. package/dist/{chunk-3WBAJKRR.js → chunk-ZPQX5ZQ2.js} +740 -555
  21. package/dist/cli.js +139 -11
  22. package/dist/index.js +4 -4
  23. package/dist/{intelligence-service-YJKQQYJQ.js → intelligence-service-2K7GVEQM.js} +2 -2
  24. package/dist/mcp.js +2 -2
  25. package/package.json +8 -8
  26. package/assets/assets/index-CfjIYitV.js +0 -210
package/dist/cli.js CHANGED
@@ -29,7 +29,7 @@ import {
29
29
  setTelemetrySource,
30
30
  showFirstRunNotice,
31
31
  trackEvent
32
- } from "./chunk-5GQ6FF5R.js";
32
+ } from "./chunk-42P7POVS.js";
33
33
  import {
34
34
  CliError,
35
35
  EXIT_SYSTEM_ERROR,
@@ -46,7 +46,7 @@ import {
46
46
  saveConfig,
47
47
  saveConfigPatch,
48
48
  usageError
49
- } from "./chunk-73HPY6XQ.js";
49
+ } from "./chunk-P4MIG7V5.js";
50
50
  import {
51
51
  apiKeys,
52
52
  createClient,
@@ -54,7 +54,7 @@ import {
54
54
  projects,
55
55
  queries,
56
56
  renderReportHtml
57
- } from "./chunk-ZXVWL5HX.js";
57
+ } from "./chunk-VPY3PZXV.js";
58
58
  import {
59
59
  AdsOperationKinds,
60
60
  AdsOperationStates,
@@ -97,7 +97,7 @@ import {
97
97
  providerQuotaPolicySchema,
98
98
  resolveProviderInput,
99
99
  winnabilityClassSchema
100
- } from "./chunk-3WBAJKRR.js";
100
+ } from "./chunk-ZPQX5ZQ2.js";
101
101
 
102
102
  // src/cli.ts
103
103
  import { pathToFileURL } from "url";
@@ -3937,6 +3937,47 @@ async function gaTraffic(project, opts) {
3937
3937
  Last synced: ${result.lastSyncedAt}`);
3938
3938
  }
3939
3939
  }
3940
+ async function gaMeasurementAnalysis(project, opts) {
3941
+ const client = getClient7();
3942
+ const params = {};
3943
+ if (opts?.window) params.window = opts.window;
3944
+ if (opts?.hostScope) params.hostScope = opts.hostScope;
3945
+ if (opts?.pathPrefix) params.pathPrefix = opts.pathPrefix;
3946
+ if (opts?.limit) params.limit = String(opts.limit);
3947
+ const result = await client.gaMeasurementAnalysis(
3948
+ project,
3949
+ Object.keys(params).length > 0 ? params : void 0
3950
+ );
3951
+ if (isMachineFormat(opts?.format)) {
3952
+ console.log(JSON.stringify(result, null, 2));
3953
+ return;
3954
+ }
3955
+ console.log(`GA4 Measurement Analysis for "${project}" (${result.window})
3956
+ `);
3957
+ console.log(` Acquisition: ${result.acquisition.status}`);
3958
+ if (result.acquisition.error) console.log(` Error: ${result.acquisition.error}`);
3959
+ for (const period of result.acquisition.periods) {
3960
+ console.log(` ${period.label.padEnd(8)} ${period.sessions} sessions ${period.startDate} to ${period.endDate}`);
3961
+ }
3962
+ if (result.acquisition.channels.length > 0) {
3963
+ console.log(" Native channels (latest cohort)");
3964
+ for (const channel of result.acquisition.channels) {
3965
+ console.log(` ${channel.channelGroup}: ${channel.periods.at(-1)?.sessions ?? 0}`);
3966
+ }
3967
+ }
3968
+ console.log(` Leads: ${result.leads.status}${result.leads.attributionScope ? ` (${result.leads.attributionScope} attribution)` : ""}`);
3969
+ if (result.leads.error) console.log(` Error: ${result.leads.error}`);
3970
+ for (const period of result.leads.periods) {
3971
+ console.log(` ${period.label.padEnd(8)} ${period.eventCount} leads ${period.startDate} to ${period.endDate}`);
3972
+ }
3973
+ console.log(` Search demand: ${result.searchDemand.status}`);
3974
+ for (const period of result.searchDemand.periods) {
3975
+ console.log(` ${period.label.padEnd(8)} ${period.propertyClicks} clicks / ${period.propertyImpressions} impressions (${period.brandedClicks} branded clicks / ${period.brandedImpressions} branded impressions; ${period.nonBrandedClicks} reported non-brand clicks / ${period.nonBrandedImpressions} reported non-brand impressions; ${period.unreportedClicks} unreported clicks / ${period.unreportedImpressions} unreported impressions)`);
3976
+ }
3977
+ if (!result.leads.hostAndPathFiltersApplied && result.leads.attributionScope === "channel") {
3978
+ console.log(" Note: lead attribution is channel-level; host and path filters do not apply to leads.");
3979
+ }
3980
+ }
3940
3981
  async function gaAiReferralHistory(project, opts) {
3941
3982
  const client = getClient7();
3942
3983
  const result = await client.gaAiReferralHistory(project, opts?.window ? { window: opts.window } : void 0);
@@ -4367,6 +4408,27 @@ var GA_CLI_COMMANDS = [
4367
4408
  });
4368
4409
  }
4369
4410
  },
4411
+ {
4412
+ path: ["ga", "measurement-analysis"],
4413
+ usage: "canonry ga measurement-analysis <project> [--window 30d|60d|90d] [--host-scope marketing|all] [--path-prefix /path] [--limit 100] [--format json]",
4414
+ options: {
4415
+ window: stringOption(),
4416
+ "host-scope": stringOption(),
4417
+ "path-prefix": stringOption(),
4418
+ limit: stringOption()
4419
+ },
4420
+ run: async (input) => {
4421
+ const project = requireProject(input, "ga.measurement-analysis", "canonry ga measurement-analysis <project> [--window 30d|60d|90d] [--format json]");
4422
+ const limitValue = getString(input.values, "limit");
4423
+ await gaMeasurementAnalysis(project, {
4424
+ window: getString(input.values, "window"),
4425
+ hostScope: getString(input.values, "host-scope"),
4426
+ pathPrefix: getString(input.values, "path-prefix"),
4427
+ limit: limitValue ? parseInt(limitValue, 10) : void 0,
4428
+ format: input.format
4429
+ });
4430
+ }
4431
+ },
4370
4432
  {
4371
4433
  path: ["ga", "traffic"],
4372
4434
  usage: "canonry ga traffic <project> [--limit 50] [--window 30d] [--format json]",
@@ -4471,7 +4533,7 @@ var GA_CLI_COMMANDS = [
4471
4533
  unknownSubcommand(input.positionals[0], {
4472
4534
  command: "ga",
4473
4535
  usage: "canonry ga <subcommand> <project> [args]",
4474
- available: ["connect", "disconnect", "status", "sync", "traffic", "coverage", "ai-referral-history", "social-referral-history", "session-history", "social-referral-summary", "attribution"]
4536
+ available: ["connect", "disconnect", "status", "sync", "measurement-analysis", "traffic", "coverage", "ai-referral-history", "social-referral-history", "session-history", "social-referral-summary", "attribution"]
4475
4537
  });
4476
4538
  }
4477
4539
  }
@@ -9343,6 +9405,70 @@ var REPORT_CLI_COMMANDS = [
9343
9405
  }
9344
9406
  ];
9345
9407
 
9408
+ // src/commands/organic-evidence.ts
9409
+ async function showOrganicEvidence(project, opts) {
9410
+ const data = await createApiClient().getOrganicEvidence(project, opts.period);
9411
+ if (isMachineFormat(opts.format)) {
9412
+ console.log(JSON.stringify(data, null, 2));
9413
+ return;
9414
+ }
9415
+ printOrganicEvidence(project, data);
9416
+ }
9417
+ function formatCounts(clicks, impressions) {
9418
+ return `${clicks} clicks / ${impressions} impressions`;
9419
+ }
9420
+ function printOrganicEvidence(project, data) {
9421
+ const asOf = data.asOfDate ? ` through ${data.asOfDate}` : "";
9422
+ console.log(`Organic evidence: ${project} (${data.periodDays} days${asOf})`);
9423
+ console.log(`Coverage: GSC ${data.coverage.gsc ? "yes" : "no"} \xB7 GA4 ${data.coverage.ga4 ? "yes" : "no"} \xB7 server ${data.coverage.server ? "yes" : "no"} \xB7 AI visibility ${data.coverage.visibility ? "yes" : "no"}`);
9424
+ if (data.gsc) {
9425
+ console.log(`Google Search: ${formatCounts(data.gsc.propertyTotals.clicks, data.gsc.propertyTotals.impressions)} (named non-brand: ${formatCounts(data.gsc.namedNonBrand.clicks, data.gsc.namedNonBrand.impressions)})`);
9426
+ }
9427
+ if (data.ga4) console.log(`GA4 organic: ${data.ga4.organicSessions} sessions`);
9428
+ if (data.gaAiReferrals) console.log(`GA4 AI referrals: ${data.gaAiReferrals.organicSessions} organic, ${data.gaAiReferrals.paidSessions} paid sessions`);
9429
+ if (data.server) {
9430
+ const s = data.server;
9431
+ const fetchTotal = s.userFetchHits.verified + s.userFetchHits.claimedUnverified + s.userFetchHits.unknownAiLike;
9432
+ console.log(`Server AI: ${s.crawlerHits.verified} verified + ${s.crawlerHits.claimedUnverified} claimed + ${s.crawlerHits.unknownAiLike} heuristic crawls; ${fetchTotal} user-agent fetches (${s.userFetchHits.verified} verified, ${s.userFetchHits.claimedUnverified} claimed, ${s.userFetchHits.unknownAiLike} heuristic); ${s.referralSessions.organic} organic referrals, ${s.referralSessions.paid} paid, ${s.referralSessions.unknown} unclassified`);
9433
+ }
9434
+ if (data.visibility) {
9435
+ const v = data.visibility;
9436
+ console.log(`Latest AI visibility: ${v.mentionedPairs}/${v.answerPairs} mentioned, ${v.citedPairs}/${v.answerPairs} cited (${Math.floor(v.ageDays)}d old)`);
9437
+ }
9438
+ if (data.findings.length > 0) {
9439
+ console.log("\nFindings:");
9440
+ for (const finding of data.findings) console.log(`- ${finding.title}: ${finding.detail}`);
9441
+ }
9442
+ if (data.limitations.length > 0) {
9443
+ console.log("\nLimitations:");
9444
+ for (const limitation of data.limitations) console.log(`- ${limitation.detail}`);
9445
+ }
9446
+ }
9447
+
9448
+ // src/cli-commands/organic-evidence.ts
9449
+ var USAGE4 = "canonry organic-evidence <project> [--period 60|90] [--format json|jsonl]";
9450
+ function parsePeriod2(value) {
9451
+ if (value === void 0) return void 0;
9452
+ if (value === "60" || value === "90") return Number(value);
9453
+ throw usageError(`Error: --period must be 60 or 90
9454
+
9455
+ Usage: ${USAGE4}`);
9456
+ }
9457
+ var ORGANIC_EVIDENCE_CLI_COMMANDS = [
9458
+ {
9459
+ path: ["organic-evidence"],
9460
+ usage: USAGE4,
9461
+ options: { period: stringOption() },
9462
+ run: async (input) => {
9463
+ const project = requireProject(input, "organic-evidence", USAGE4);
9464
+ await showOrganicEvidence(project, {
9465
+ period: parsePeriod2(getString(input.values, "period")),
9466
+ format: input.format
9467
+ });
9468
+ }
9469
+ }
9470
+ ];
9471
+
9346
9472
  // src/commands/run.ts
9347
9473
  function getClient22() {
9348
9474
  return createApiClient();
@@ -13242,12 +13368,12 @@ function printVisibilityStats(data) {
13242
13368
  }
13243
13369
 
13244
13370
  // src/cli-commands/visibility-stats.ts
13245
- var USAGE4 = "canonry visibility-stats <project> [--since <iso>] [--until <iso>] [--month <YYYY-MM>] [--last-runs <n>] [--by-provider] [--share-of-voice] [--format json|jsonl]";
13371
+ var USAGE5 = "canonry visibility-stats <project> [--since <iso>] [--until <iso>] [--month <YYYY-MM>] [--last-runs <n>] [--by-provider] [--share-of-voice] [--format json|jsonl]";
13246
13372
  var COMPARE_USAGE = "canonry visibility-compare <project> --from <YYYY-MM> --to <YYYY-MM> [--format json]";
13247
13373
  var VISIBILITY_STATS_CLI_COMMANDS = [
13248
13374
  {
13249
13375
  path: ["visibility-stats"],
13250
- usage: USAGE4,
13376
+ usage: USAGE5,
13251
13377
  options: {
13252
13378
  since: stringOption(),
13253
13379
  until: stringOption(),
@@ -13257,14 +13383,14 @@ var VISIBILITY_STATS_CLI_COMMANDS = [
13257
13383
  "share-of-voice": { type: "boolean", default: false }
13258
13384
  },
13259
13385
  run: async (input) => {
13260
- const project = requireProject(input, "visibility-stats", USAGE4);
13386
+ const project = requireProject(input, "visibility-stats", USAGE5);
13261
13387
  await showVisibilityStats(project, {
13262
13388
  since: getString(input.values, "since"),
13263
13389
  until: getString(input.values, "until"),
13264
13390
  month: getString(input.values, "month"),
13265
13391
  lastRuns: parseIntegerOption(input, "last-runs", {
13266
13392
  command: "visibility-stats",
13267
- usage: USAGE4,
13393
+ usage: USAGE5,
13268
13394
  message: "--last-runs must be an integer"
13269
13395
  }),
13270
13396
  byProvider: getBoolean(input.values, "by-provider"),
@@ -14871,6 +14997,7 @@ var REGISTERED_CLI_COMMANDS = [
14871
14997
  ...SYSTEM_CLI_COMMANDS,
14872
14998
  ...PROJECT_CLI_COMMANDS,
14873
14999
  ...REPORT_CLI_COMMANDS,
15000
+ ...ORGANIC_EVIDENCE_CLI_COMMANDS,
14874
15001
  ...QUERY_CLI_COMMANDS,
14875
15002
  ...KEYWORD_CLI_COMMANDS,
14876
15003
  ...KEYS_CLI_COMMANDS,
@@ -14904,7 +15031,7 @@ var REGISTERED_CLI_COMMANDS = [
14904
15031
 
14905
15032
  // src/cli.ts
14906
15033
  import { createRequire as createRequire2 } from "module";
14907
- var USAGE5 = `
15034
+ var USAGE6 = `
14908
15035
  cnry \u2014 AEO monitoring CLI ('canonry' also works)
14909
15036
 
14910
15037
  Usage: cnry <command> [options]
@@ -14927,6 +15054,7 @@ Monitoring:
14927
15054
  status <project> Show project summary
14928
15055
  evidence <project> Show per-query results
14929
15056
  analytics <project> Show analytics (metrics, gaps, sources)
15057
+ organic-evidence Reconcile 60/90d search, GA4, and server AI evidence
14930
15058
  insights <project> Show intelligence insights
14931
15059
  health <project> Show citation health
14932
15060
 
@@ -14969,7 +15097,7 @@ function extractFormat(cmdArgs) {
14969
15097
  }
14970
15098
  async function runCli(args = process.argv.slice(2)) {
14971
15099
  if (args.length === 0 || args[0] === "--help" || args[0] === "-h") {
14972
- console.log(USAGE5);
15100
+ console.log(USAGE6);
14973
15101
  return 0;
14974
15102
  }
14975
15103
  if (args.includes("--version") || args.includes("-v")) {
package/dist/index.js CHANGED
@@ -1,11 +1,11 @@
1
1
  import {
2
2
  createServer
3
- } from "./chunk-5GQ6FF5R.js";
3
+ } from "./chunk-42P7POVS.js";
4
4
  import {
5
5
  loadConfig
6
- } from "./chunk-73HPY6XQ.js";
7
- import "./chunk-ZXVWL5HX.js";
8
- import "./chunk-3WBAJKRR.js";
6
+ } from "./chunk-P4MIG7V5.js";
7
+ import "./chunk-VPY3PZXV.js";
8
+ import "./chunk-ZPQX5ZQ2.js";
9
9
  export {
10
10
  createServer,
11
11
  loadConfig
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  IntelligenceService
3
- } from "./chunk-ZXVWL5HX.js";
4
- import "./chunk-3WBAJKRR.js";
3
+ } from "./chunk-VPY3PZXV.js";
4
+ import "./chunk-ZPQX5ZQ2.js";
5
5
  export {
6
6
  IntelligenceService
7
7
  };
package/dist/mcp.js CHANGED
@@ -3,10 +3,10 @@ import {
3
3
  PACKAGE_VERSION,
4
4
  canonryMcpTools,
5
5
  createApiClient
6
- } from "./chunk-73HPY6XQ.js";
6
+ } from "./chunk-P4MIG7V5.js";
7
7
  import {
8
8
  isReadOnlyKey
9
- } from "./chunk-3WBAJKRR.js";
9
+ } from "./chunk-ZPQX5ZQ2.js";
10
10
 
11
11
  // src/mcp/cli.ts
12
12
  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.131.0",
3
+ "version": "4.133.0",
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",
@@ -66,26 +66,26 @@
66
66
  "tsup": "^8.5.1",
67
67
  "tsx": "^4.19.0",
68
68
  "@ainyc/canonry-api-client": "0.0.0",
69
- "@ainyc/canonry-contracts": "0.0.0",
70
69
  "@ainyc/canonry-api-routes": "0.0.0",
71
70
  "@ainyc/canonry-config": "0.0.0",
71
+ "@ainyc/canonry-contracts": "0.0.0",
72
72
  "@ainyc/canonry-db": "0.0.0",
73
73
  "@ainyc/canonry-integration-bing": "0.0.0",
74
74
  "@ainyc/canonry-integration-openai-ads": "0.0.0",
75
75
  "@ainyc/canonry-integration-cloud-run": "0.0.0",
76
76
  "@ainyc/canonry-integration-google": "0.0.0",
77
+ "@ainyc/canonry-integration-commoncrawl": "0.0.0",
77
78
  "@ainyc/canonry-integration-google-business-profile": "0.0.0",
78
79
  "@ainyc/canonry-integration-google-places": "0.0.0",
79
80
  "@ainyc/canonry-integration-traffic": "0.0.0",
80
- "@ainyc/canonry-integration-commoncrawl": "0.0.0",
81
81
  "@ainyc/canonry-intelligence": "0.0.0",
82
- "@ainyc/canonry-integration-wordpress": "0.0.0",
83
- "@ainyc/canonry-provider-claude": "0.0.0",
84
- "@ainyc/canonry-provider-gemini": "0.0.0",
85
82
  "@ainyc/canonry-provider-cdp": "0.0.0",
83
+ "@ainyc/canonry-provider-claude": "0.0.0",
84
+ "@ainyc/canonry-integration-wordpress": "0.0.0",
86
85
  "@ainyc/canonry-provider-local": "0.0.0",
87
- "@ainyc/canonry-provider-perplexity": "0.0.0",
88
- "@ainyc/canonry-provider-openai": "0.0.0"
86
+ "@ainyc/canonry-provider-gemini": "0.0.0",
87
+ "@ainyc/canonry-provider-openai": "0.0.0",
88
+ "@ainyc/canonry-provider-perplexity": "0.0.0"
89
89
  },
90
90
  "scripts": {
91
91
  "build": "tsx scripts/copy-agent-assets.ts && tsup && tsx build-web.ts",