@ainyc/canonry 4.84.0 → 4.85.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 (24) hide show
  1. package/assets/agent-workspace/skills/aero/references/regression-playbook.md +2 -0
  2. package/assets/agent-workspace/skills/canonry/references/canonry-cli.md +19 -0
  3. package/assets/assets/{BacklinksPage-OrSg_iPA.js → BacklinksPage-CDAv0ggn.js} +1 -1
  4. package/assets/assets/{ChartPrimitives-DPBhAT_r.js → ChartPrimitives-CnAmsyt7.js} +1 -1
  5. package/assets/assets/{ProjectPage-CpMcEmtw.js → ProjectPage-C9KEgRxD.js} +1 -1
  6. package/assets/assets/{RunRow-2Rty0BAH.js → RunRow-CVZ5o8fg.js} +1 -1
  7. package/assets/assets/{RunsPage-B3ahqf8s.js → RunsPage-Bzy5c0MZ.js} +1 -1
  8. package/assets/assets/{SettingsPage-BIjeI85q.js → SettingsPage-B1ocxPBe.js} +1 -1
  9. package/assets/assets/{TrafficPage-DjGoj691.js → TrafficPage-D2zepQOC.js} +1 -1
  10. package/assets/assets/{TrafficSourceDetailPage-BgKG-2q3.js → TrafficSourceDetailPage-C7JuAkaK.js} +1 -1
  11. package/assets/assets/{arrow-left-Cf7wmru1.js → arrow-left-Bv3CWylm.js} +1 -1
  12. package/assets/assets/{extract-error-message-CANxezte.js → extract-error-message-BtVid5TP.js} +1 -1
  13. package/assets/assets/{index-CGlPx_cu.js → index-DmNti_xn.js} +72 -72
  14. package/assets/assets/{trash-2-6nHJZrvy.js → trash-2-BoimCsYz.js} +1 -1
  15. package/assets/index.html +1 -1
  16. package/dist/{chunk-VJBO4VIK.js → chunk-3K3QRSYE.js} +620 -422
  17. package/dist/{chunk-Y3O3HBMN.js → chunk-62YB3ML7.js} +49 -1
  18. package/dist/{chunk-M3IYKTSF.js → chunk-7BMSWI2K.js} +4 -4
  19. package/dist/{chunk-BNF3HXBW.js → chunk-I2BJC3DT.js} +1021 -942
  20. package/dist/cli.js +151 -20
  21. package/dist/index.js +4 -4
  22. package/dist/{intelligence-service-PDIAMP5I.js → intelligence-service-AHHBQKRD.js} +2 -2
  23. package/dist/mcp.js +2 -2
  24. package/package.json +9 -9
package/dist/cli.js CHANGED
@@ -27,7 +27,7 @@ import {
27
27
  setTelemetrySource,
28
28
  showFirstRunNotice,
29
29
  trackEvent
30
- } from "./chunk-M3IYKTSF.js";
30
+ } from "./chunk-7BMSWI2K.js";
31
31
  import {
32
32
  CliError,
33
33
  EXIT_SYSTEM_ERROR,
@@ -44,7 +44,7 @@ import {
44
44
  saveConfig,
45
45
  saveConfigPatch,
46
46
  usageError
47
- } from "./chunk-Y3O3HBMN.js";
47
+ } from "./chunk-62YB3ML7.js";
48
48
  import {
49
49
  apiKeys,
50
50
  createClient,
@@ -52,7 +52,7 @@ import {
52
52
  projects,
53
53
  queries,
54
54
  renderReportHtml
55
- } from "./chunk-VJBO4VIK.js";
55
+ } from "./chunk-3K3QRSYE.js";
56
56
  import {
57
57
  BacklinkSources,
58
58
  CcReleaseSyncStatuses,
@@ -70,13 +70,14 @@ import {
70
70
  formatGbpMetricLabel,
71
71
  formatIsoDate,
72
72
  formatMicros,
73
+ formatRatio,
73
74
  formatRunErrorOneLine,
74
75
  normalizeProjectAliases,
75
76
  notificationEventSchema,
76
77
  providerQuotaPolicySchema,
77
78
  resolveProviderInput,
78
79
  winnabilityClassSchema
79
- } from "./chunk-BNF3HXBW.js";
80
+ } from "./chunk-I2BJC3DT.js";
80
81
 
81
82
  // src/cli.ts
82
83
  import { pathToFileURL } from "url";
@@ -2868,7 +2869,7 @@ async function gaSocialReferralSummary(project, opts) {
2868
2869
  console.log(` Sessions: ${traffic.socialSessions} (${traffic.socialSharePct}% of ${traffic.totalSessions} total)`);
2869
2870
  console.log(` Users: ${traffic.socialUsers}`);
2870
2871
  console.log();
2871
- const fmtTrend = (pct3) => pct3 === null ? "n/a" : `${pct3 >= 0 ? "+" : ""}${pct3}%`;
2872
+ const fmtTrend = (pct4) => pct4 === null ? "n/a" : `${pct4 >= 0 ? "+" : ""}${pct4}%`;
2872
2873
  console.log(` 7d trend: ${fmtTrend(trend.trend7dPct)} (${trend.socialSessions7d} vs ${trend.socialSessionsPrev7d})`);
2873
2874
  console.log(` 30d trend: ${fmtTrend(trend.trend30dPct)} (${trend.socialSessions30d} vs ${trend.socialSessionsPrev30d})`);
2874
2875
  if (trend.biggestMover) {
@@ -2911,7 +2912,7 @@ async function gaSocialReferralSummary(project, opts) {
2911
2912
  async function gaAttribution(project, opts) {
2912
2913
  const client = getClient6();
2913
2914
  const traffic = await client.gaTraffic(project);
2914
- const fmtTrend = (pct3) => pct3 === null ? "n/a" : `${pct3 >= 0 ? "+" : ""}${pct3}%`;
2915
+ const fmtTrend = (pct4) => pct4 === null ? "n/a" : `${pct4 >= 0 ? "+" : ""}${pct4}%`;
2915
2916
  if (opts?.trend) {
2916
2917
  const trend = await client.gaAttributionTrend(project);
2917
2918
  if (isMachineFormat(opts.format)) {
@@ -3475,9 +3476,9 @@ async function gbpPlaces(project, opts) {
3475
3476
  console.log(` ${p.locationName} [${p.tier}] ${amenities}`);
3476
3477
  }
3477
3478
  }
3478
- function fmtDelta(pct3) {
3479
- if (pct3 === null) return "n/a";
3480
- return `${pct3 >= 0 ? "+" : ""}${pct3}%`;
3479
+ function fmtDelta(pct4) {
3480
+ if (pct4 === null) return "n/a";
3481
+ return `${pct4 >= 0 ? "+" : ""}${pct4}%`;
3481
3482
  }
3482
3483
  async function gbpSummary(project, opts) {
3483
3484
  const client = getClient7();
@@ -6951,14 +6952,14 @@ function printMetrics(data) {
6951
6952
  console.log(`
6952
6953
  Citation Rate Trends (${data.window})`);
6953
6954
  console.log("\u2500".repeat(50));
6954
- const pct3 = (n) => `${(n * 100).toFixed(1)}%`;
6955
- console.log(` Overall: ${pct3(data.overall.citationRate)} (${data.overall.cited}/${data.overall.total})`);
6955
+ const pct4 = (n) => `${(n * 100).toFixed(1)}%`;
6956
+ console.log(` Overall: ${pct4(data.overall.citationRate)} (${data.overall.cited}/${data.overall.total})`);
6956
6957
  console.log(` Trend: ${data.trend}`);
6957
6958
  if (Object.keys(data.byProvider).length > 0) {
6958
6959
  console.log(`
6959
6960
  By Provider:`);
6960
6961
  for (const [provider, metric] of Object.entries(data.byProvider)) {
6961
- console.log(` ${provider.padEnd(10)} ${pct3(metric.citationRate).padStart(6)} (${metric.cited}/${metric.total})`);
6962
+ console.log(` ${provider.padEnd(10)} ${pct4(metric.citationRate).padStart(6)} (${metric.cited}/${metric.total})`);
6962
6963
  }
6963
6964
  }
6964
6965
  if (data.buckets.length > 0) {
@@ -6967,7 +6968,7 @@ Citation Rate Trends (${data.window})`);
6967
6968
  for (const bucket of data.buckets) {
6968
6969
  const start = bucket.startDate.slice(0, 10);
6969
6970
  const bar = bucket.total > 0 ? "\u2588".repeat(Math.round(bucket.citationRate * 20)) : "";
6970
- console.log(` ${start} ${pct3(bucket.citationRate).padStart(6)} ${bar}`);
6971
+ console.log(` ${start} ${pct4(bucket.citationRate).padStart(6)} ${bar}`);
6971
6972
  }
6972
6973
  }
6973
6974
  const providersInBuckets = [...new Set(data.buckets.flatMap((b) => Object.keys(b.byProvider ?? {})))].sort();
@@ -6981,7 +6982,7 @@ Citation Rate Trends (${data.window})`);
6981
6982
  if (!metric) continue;
6982
6983
  const start = bucket.startDate.slice(0, 10);
6983
6984
  const bar = metric.total > 0 ? "\u2588".repeat(Math.round(metric.citationRate * 20)) : "";
6984
- console.log(` ${start} ${pct3(metric.citationRate).padStart(6)} ${bar}`);
6985
+ console.log(` ${start} ${pct4(metric.citationRate).padStart(6)} ${bar}`);
6985
6986
  }
6986
6987
  }
6987
6988
  }
@@ -7019,9 +7020,9 @@ Source Origin Breakdown`);
7019
7020
  return;
7020
7021
  }
7021
7022
  for (const cat of data.overall) {
7022
- const pct3 = `${(cat.percentage * 100).toFixed(1)}%`;
7023
+ const pct4 = `${(cat.percentage * 100).toFixed(1)}%`;
7023
7024
  const domains = cat.topDomains.slice(0, 3).map((d) => d.domain).join(", ");
7024
- console.log(` ${cat.label.padEnd(20)} ${pct3.padStart(6)} (${cat.count}) ${domains}`);
7025
+ console.log(` ${cat.label.padEnd(20)} ${pct4.padStart(6)} (${cat.count}) ${domains}`);
7025
7026
  }
7026
7027
  }
7027
7028
 
@@ -9455,8 +9456,8 @@ function printMentionShareBreakdown(mentionShare) {
9455
9456
  const youPct = (breakdown.projectMentionSnapshots / total * 100).toFixed(1);
9456
9457
  console.log(` you${" ".repeat(28)} ${breakdown.projectMentionSnapshots} mentions (${youPct}% of combined)`);
9457
9458
  for (const row of breakdown.perCompetitor.slice(0, 3)) {
9458
- const pct3 = (row.mentionSnapshots / total * 100).toFixed(1);
9459
- console.log(` ${row.domain.padEnd(30)} ${row.mentionSnapshots} mentions (${pct3}% of combined)`);
9459
+ const pct4 = (row.mentionSnapshots / total * 100).toFixed(1);
9460
+ console.log(` ${row.domain.padEnd(30)} ${row.mentionSnapshots} mentions (${pct4}% of combined)`);
9460
9461
  }
9461
9462
  if (breakdown.perCompetitor.length > 3) {
9462
9463
  console.log(` + ${breakdown.perCompetitor.length - 3} more competitor${breakdown.perCompetitor.length - 3 === 1 ? "" : "s"} (--format json for full breakdown)`);
@@ -11266,6 +11267,135 @@ var TECHNICAL_AEO_CLI_COMMANDS = [
11266
11267
  }
11267
11268
  ];
11268
11269
 
11270
+ // src/commands/visibility-stats.ts
11271
+ async function showVisibilityStats(project, opts) {
11272
+ const client = createApiClient();
11273
+ const data = await client.getVisibilityStats(project, {
11274
+ since: opts.since,
11275
+ until: opts.until,
11276
+ lastRuns: opts.lastRuns,
11277
+ groupBy: opts.byProvider ? "provider" : void 0
11278
+ });
11279
+ if (opts.format === "jsonl") {
11280
+ emitJsonl(data.queries.map((q) => ({ project: data.project, runCount: data.window.runCount, ...q })));
11281
+ return;
11282
+ }
11283
+ if (opts.format === "json") {
11284
+ console.log(JSON.stringify(data, null, 2));
11285
+ return;
11286
+ }
11287
+ printVisibilityStats(data);
11288
+ }
11289
+ function pct3(rate) {
11290
+ return rate === null ? "\u2014" : formatRatio(rate);
11291
+ }
11292
+ function citedCell(c) {
11293
+ return `${c.cited}/${c.total}`;
11294
+ }
11295
+ function mentionedCell(c) {
11296
+ return `${c.mentioned}/${c.checked}`;
11297
+ }
11298
+ function printVisibilityStats(data) {
11299
+ const w = data.window;
11300
+ const windowParts = [`${w.runCount} run(s)`];
11301
+ if (w.lastRuns !== null) windowParts.push(`last ${w.lastRuns}`);
11302
+ if (w.since !== null) windowParts.push(`since ${w.since}`);
11303
+ if (w.until !== null) windowParts.push(`until ${w.until}`);
11304
+ console.log("Visibility stats (cited = source list, mentioned = answer text)");
11305
+ console.log(`Window: ${windowParts.join(" \xB7 ")}`);
11306
+ console.log('Cited = cited/total snapshots \xB7 Mentioned = mentioned/checked (checked excludes "not checked")');
11307
+ console.log("");
11308
+ if (data.queries.length === 0) {
11309
+ console.log("No answer-visibility snapshots in this window \u2014 run a sweep first (canonry run <project>).");
11310
+ return;
11311
+ }
11312
+ const rows = data.queries.map((q) => ({
11313
+ label: q.query,
11314
+ cited: citedCell(q),
11315
+ citedPct: pct3(q.citedRate),
11316
+ ment: mentionedCell(q),
11317
+ mentPct: pct3(q.mentionRate)
11318
+ }));
11319
+ const queryWidth = Math.max(7, ...rows.map((r) => r.label.length));
11320
+ const citedWidth = Math.max(7, ...rows.map((r) => r.cited.length));
11321
+ const mentWidth = Math.max(9, ...rows.map((r) => r.ment.length));
11322
+ const header = [
11323
+ "Query".padEnd(queryWidth),
11324
+ "Cited".padEnd(citedWidth),
11325
+ "Cited%".padStart(7),
11326
+ "Mentioned".padEnd(mentWidth),
11327
+ "Ment%".padStart(7)
11328
+ ].join(" ");
11329
+ console.log(header);
11330
+ console.log("\u2500".repeat(header.length));
11331
+ for (const r of rows) {
11332
+ console.log(
11333
+ [
11334
+ r.label.padEnd(queryWidth),
11335
+ r.cited.padEnd(citedWidth),
11336
+ r.citedPct.padStart(7),
11337
+ r.ment.padEnd(mentWidth),
11338
+ r.mentPct.padStart(7)
11339
+ ].join(" ")
11340
+ );
11341
+ }
11342
+ console.log("\u2500".repeat(header.length));
11343
+ console.log(
11344
+ [
11345
+ "TOTAL".padEnd(queryWidth),
11346
+ citedCell(data.totals).padEnd(citedWidth),
11347
+ pct3(data.totals.citedRate).padStart(7),
11348
+ mentionedCell(data.totals).padEnd(mentWidth),
11349
+ pct3(data.totals.mentionRate).padStart(7)
11350
+ ].join(" ")
11351
+ );
11352
+ if (data.groupBy === "provider" && data.byProvider && data.byProvider.length > 0) {
11353
+ console.log("");
11354
+ console.log("By provider (pooled across queries):");
11355
+ const provWidth = Math.max(8, ...data.byProvider.map((p) => p.provider.length));
11356
+ for (const p of data.byProvider) {
11357
+ console.log(
11358
+ [
11359
+ ` ${p.provider}`.padEnd(provWidth + 2),
11360
+ citedCell(p).padEnd(citedWidth),
11361
+ pct3(p.citedRate).padStart(7),
11362
+ mentionedCell(p).padEnd(mentWidth),
11363
+ pct3(p.mentionRate).padStart(7)
11364
+ ].join(" ")
11365
+ );
11366
+ }
11367
+ }
11368
+ }
11369
+
11370
+ // src/cli-commands/visibility-stats.ts
11371
+ var USAGE4 = "canonry visibility-stats <project> [--since <iso>] [--until <iso>] [--last-runs <n>] [--by-provider] [--format json|jsonl]";
11372
+ var VISIBILITY_STATS_CLI_COMMANDS = [
11373
+ {
11374
+ path: ["visibility-stats"],
11375
+ usage: USAGE4,
11376
+ options: {
11377
+ since: stringOption(),
11378
+ until: stringOption(),
11379
+ "last-runs": stringOption(),
11380
+ "by-provider": { type: "boolean", default: false }
11381
+ },
11382
+ run: async (input) => {
11383
+ const project = requireProject(input, "visibility-stats", USAGE4);
11384
+ await showVisibilityStats(project, {
11385
+ since: getString(input.values, "since"),
11386
+ until: getString(input.values, "until"),
11387
+ lastRuns: parseIntegerOption(input, "last-runs", {
11388
+ command: "visibility-stats",
11389
+ usage: USAGE4,
11390
+ message: "--last-runs must be an integer"
11391
+ }),
11392
+ byProvider: getBoolean(input.values, "by-provider"),
11393
+ format: input.format
11394
+ });
11395
+ }
11396
+ }
11397
+ ];
11398
+
11269
11399
  // src/cli-commands/wordpress.ts
11270
11400
  import fs11 from "fs";
11271
11401
 
@@ -12850,6 +12980,7 @@ var REGISTERED_CLI_COMMANDS = [
12850
12980
  ...GBP_CLI_COMMANDS,
12851
12981
  ...TRAFFIC_CLI_COMMANDS,
12852
12982
  ...INTELLIGENCE_CLI_COMMANDS,
12983
+ ...VISIBILITY_STATS_CLI_COMMANDS,
12853
12984
  ...CONTENT_CLI_COMMANDS,
12854
12985
  ...AGENT_CLI_COMMANDS,
12855
12986
  ...DISCOVER_CLI_COMMANDS,
@@ -12861,7 +12992,7 @@ var REGISTERED_CLI_COMMANDS = [
12861
12992
 
12862
12993
  // src/cli.ts
12863
12994
  import { createRequire as createRequire2 } from "module";
12864
- var USAGE4 = `
12995
+ var USAGE5 = `
12865
12996
  cnry \u2014 AEO monitoring CLI ('canonry' also works)
12866
12997
 
12867
12998
  Usage: cnry <command> [options]
@@ -12926,7 +13057,7 @@ function extractFormat(cmdArgs) {
12926
13057
  }
12927
13058
  async function runCli(args = process.argv.slice(2)) {
12928
13059
  if (args.length === 0 || args[0] === "--help" || args[0] === "-h") {
12929
- console.log(USAGE4);
13060
+ console.log(USAGE5);
12930
13061
  return 0;
12931
13062
  }
12932
13063
  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-M3IYKTSF.js";
3
+ } from "./chunk-7BMSWI2K.js";
4
4
  import {
5
5
  loadConfig
6
- } from "./chunk-Y3O3HBMN.js";
7
- import "./chunk-VJBO4VIK.js";
8
- import "./chunk-BNF3HXBW.js";
6
+ } from "./chunk-62YB3ML7.js";
7
+ import "./chunk-3K3QRSYE.js";
8
+ import "./chunk-I2BJC3DT.js";
9
9
  export {
10
10
  createServer,
11
11
  loadConfig
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  IntelligenceService
3
- } from "./chunk-VJBO4VIK.js";
4
- import "./chunk-BNF3HXBW.js";
3
+ } from "./chunk-3K3QRSYE.js";
4
+ import "./chunk-I2BJC3DT.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-Y3O3HBMN.js";
6
+ } from "./chunk-62YB3ML7.js";
7
7
  import {
8
8
  isReadOnlyKey
9
- } from "./chunk-BNF3HXBW.js";
9
+ } from "./chunk-I2BJC3DT.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": "@ainyc/canonry",
3
- "version": "4.84.0",
3
+ "version": "4.85.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",
@@ -62,26 +62,26 @@
62
62
  "@types/node-cron": "^3.0.11",
63
63
  "tsup": "^8.5.1",
64
64
  "tsx": "^4.19.0",
65
+ "@ainyc/canonry-config": "0.0.0",
65
66
  "@ainyc/canonry-api-client": "0.0.0",
66
- "@ainyc/canonry-db": "0.0.0",
67
67
  "@ainyc/canonry-api-routes": "0.0.0",
68
- "@ainyc/canonry-contracts": "0.0.0",
69
- "@ainyc/canonry-config": "0.0.0",
68
+ "@ainyc/canonry-db": "0.0.0",
70
69
  "@ainyc/canonry-integration-bing": "0.0.0",
71
- "@ainyc/canonry-integration-cloud-run": "0.0.0",
72
70
  "@ainyc/canonry-integration-openai-ads": "0.0.0",
71
+ "@ainyc/canonry-integration-cloud-run": "0.0.0",
72
+ "@ainyc/canonry-contracts": "0.0.0",
73
73
  "@ainyc/canonry-integration-commoncrawl": "0.0.0",
74
74
  "@ainyc/canonry-integration-google": "0.0.0",
75
75
  "@ainyc/canonry-integration-google-business-profile": "0.0.0",
76
76
  "@ainyc/canonry-integration-google-places": "0.0.0",
77
- "@ainyc/canonry-intelligence": "0.0.0",
78
77
  "@ainyc/canonry-integration-traffic": "0.0.0",
79
- "@ainyc/canonry-provider-claude": "0.0.0",
80
- "@ainyc/canonry-provider-cdp": "0.0.0",
78
+ "@ainyc/canonry-intelligence": "0.0.0",
81
79
  "@ainyc/canonry-integration-wordpress": "0.0.0",
80
+ "@ainyc/canonry-provider-cdp": "0.0.0",
82
81
  "@ainyc/canonry-provider-gemini": "0.0.0",
83
- "@ainyc/canonry-provider-openai": "0.0.0",
84
82
  "@ainyc/canonry-provider-local": "0.0.0",
83
+ "@ainyc/canonry-provider-claude": "0.0.0",
84
+ "@ainyc/canonry-provider-openai": "0.0.0",
85
85
  "@ainyc/canonry-provider-perplexity": "0.0.0"
86
86
  },
87
87
  "scripts": {