@canonry/canonry 4.116.0 → 4.117.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.
Files changed (26) hide show
  1. package/README.md +0 -1
  2. package/assets/agent-workspace/skills/aero/references/reporting.md +10 -0
  3. package/assets/agent-workspace/skills/canonry/references/canonry-cli.md +6 -0
  4. package/assets/assets/{BacklinksPage-Dy6Xc-LT.js → BacklinksPage-Bkafm10m.js} +1 -1
  5. package/assets/assets/{ChartPrimitives-CHJh5M8x.js → ChartPrimitives-NV_GgqFn.js} +1 -1
  6. package/assets/assets/{ProjectPage-Bjfa4CI5.js → ProjectPage-0-NnRxys.js} +1 -1
  7. package/assets/assets/{RunRow-DmvQnWPf.js → RunRow-df0d24S6.js} +1 -1
  8. package/assets/assets/{RunsPage-BxkxQEKE.js → RunsPage-CU6-4YTM.js} +1 -1
  9. package/assets/assets/{SettingsPage-DCyqHqDh.js → SettingsPage-BKw6B6cd.js} +1 -1
  10. package/assets/assets/{TrafficPage-BT_ae5aO.js → TrafficPage-CzpiYHKj.js} +1 -1
  11. package/assets/assets/{TrafficSourceDetailPage-Cps-tSHn.js → TrafficSourceDetailPage-CC5nuqM1.js} +1 -1
  12. package/assets/assets/{arrow-left-D8vdqhx4.js → arrow-left-CbQcW2pL.js} +1 -1
  13. package/assets/assets/{extract-error-message-BOY5txUA.js → extract-error-message-CvqIZ-le.js} +1 -1
  14. package/assets/assets/index-LjcWHaNZ.js +210 -0
  15. package/assets/assets/{trash-2-ap_Fa4zA.js → trash-2-3J2u0woR.js} +1 -1
  16. package/assets/index.html +1 -1
  17. package/dist/{chunk-RVH6QPTA.js → chunk-BMBHUFMI.js} +50 -1
  18. package/dist/{chunk-IQPMK36Y.js → chunk-IAJ5TQ4S.js} +155 -3
  19. package/dist/{chunk-GV665WOU.js → chunk-NY7SC4ES.js} +6 -5
  20. package/dist/{chunk-WEAXJ25Y.js → chunk-V4SW7SVX.js} +1083 -667
  21. package/dist/cli.js +93 -4
  22. package/dist/index.js +4 -4
  23. package/dist/{intelligence-service-HEN5HLUM.js → intelligence-service-C5YLASIP.js} +2 -2
  24. package/dist/mcp.js +2 -2
  25. package/package.json +10 -10
  26. package/assets/assets/index-DxjY63VC.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-GV665WOU.js";
32
+ } from "./chunk-NY7SC4ES.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-RVH6QPTA.js";
49
+ } from "./chunk-BMBHUFMI.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-WEAXJ25Y.js";
57
+ } from "./chunk-V4SW7SVX.js";
58
58
  import {
59
59
  BacklinkSources,
60
60
  CcReleaseSyncStatuses,
@@ -80,7 +80,7 @@ import {
80
80
  providerQuotaPolicySchema,
81
81
  resolveProviderInput,
82
82
  winnabilityClassSchema
83
- } from "./chunk-IQPMK36Y.js";
83
+ } from "./chunk-IAJ5TQ4S.js";
84
84
 
85
85
  // src/cli.ts
86
86
  import { pathToFileURL } from "url";
@@ -11841,6 +11841,78 @@ async function showVisibilityStats(project, opts) {
11841
11841
  function pct3(rate) {
11842
11842
  return rate === null ? "\u2014" : formatRatio(rate);
11843
11843
  }
11844
+ async function showVisibilityCompare(project, opts) {
11845
+ if (!opts.from || !opts.to) throw new Error("visibility-compare requires --from <YYYY-MM> and --to <YYYY-MM>");
11846
+ const client = createApiClient();
11847
+ const data = await client.getVisibilityCompare(project, opts.from, opts.to);
11848
+ if (isMachineFormat(opts.format)) {
11849
+ console.log(JSON.stringify(data, null, 2));
11850
+ return;
11851
+ }
11852
+ printVisibilityCompare(data);
11853
+ }
11854
+ function periodCell(p) {
11855
+ if (p.point === null || p.ciLow === null || p.ciHigh === null) return "no data";
11856
+ const p1 = (v) => formatRatio(v);
11857
+ return `${p1(p.point)} [${p1(p.ciLow)}, ${p1(p.ciHigh)}]`;
11858
+ }
11859
+ function verdictCell(m) {
11860
+ switch (m.verdict) {
11861
+ case "within-noise":
11862
+ return "within noise";
11863
+ case "insufficient-data":
11864
+ return "no data";
11865
+ case "moved":
11866
+ return `moved ${m.direction === "down" ? "down" : m.direction === "up" ? "up" : ""}`.trim();
11867
+ case "model-discontinuous":
11868
+ return "model discontinuity";
11869
+ case "model-unknown":
11870
+ return "model unknown";
11871
+ }
11872
+ }
11873
+ function printVisibilityCompare(data) {
11874
+ console.log(`AEO month over month: ${data.project} ${data.from.month} -> ${data.to.month}`);
11875
+ const b = data.basket;
11876
+ const excl = [];
11877
+ if (b.excludedFromOnly > 0) excl.push(`${b.excludedFromOnly} only in ${data.from.month}`);
11878
+ if (b.excludedToOnly > 0) excl.push(`${b.excludedToOnly} only in ${data.to.month}`);
11879
+ if (b.excludedProviders.length > 0) excl.push(`engines dropped: ${b.excludedProviders.join(", ")}`);
11880
+ console.log(`Basket: ${b.queryCount} quer${b.queryCount === 1 ? "y" : "ies"}, ${b.providers.length} engine(s)${excl.length ? ` (excluded: ${excl.join("; ")})` : ""}`);
11881
+ const sweeps = `Sweeps: ${data.from.month} ${data.from.runCount}, ${data.to.month} ${data.to.runCount}`;
11882
+ const low = data.from.lowRunCount || data.to.lowRunCount;
11883
+ console.log(low ? `${sweeps} (below the 5-sweep floor \u2014 intervals are wide, a "moved" verdict is unlikely to be reachable)` : sweeps);
11884
+ if (data.continuity.status !== "comparable") {
11885
+ console.log(`Continuity: ${data.continuity.status.replace("-", " ")} \u2014 no directional call is made.`);
11886
+ }
11887
+ console.log("");
11888
+ const rows = data.metrics.map((m) => ({
11889
+ label: `${m.label}${m.driftRobust ? " *" : ""}`,
11890
+ to: periodCell(m.to),
11891
+ from: periodCell(m.from),
11892
+ verdict: verdictCell(m)
11893
+ }));
11894
+ rows.push({
11895
+ label: "Queries named (count)",
11896
+ to: `${data.queriesMentioned.to.count} of ${data.queriesMentioned.to.of}`,
11897
+ from: `${data.queriesMentioned.from.count} of ${data.queriesMentioned.from.of}`,
11898
+ verdict: ""
11899
+ });
11900
+ const w = (sel, head) => Math.max(head.length, ...rows.map((r) => sel(r).length));
11901
+ const lw = w((r) => r.label, "Metric");
11902
+ const tw = w((r) => r.to, data.to.month);
11903
+ const fw = w((r) => r.from, data.from.month);
11904
+ console.log(` ${"Metric".padEnd(lw)} ${data.to.month.padEnd(tw)} ${data.from.month.padEnd(fw)} Verdict`);
11905
+ for (const r of rows) {
11906
+ console.log(` ${r.label.padEnd(lw)} ${r.to.padEnd(tw)} ${r.from.padEnd(fw)} ${r.verdict}`);
11907
+ }
11908
+ console.log("");
11909
+ console.log(" * share of voice is less exposed to broad model-wide naming propensity; model continuity is still required.");
11910
+ for (const provider of data.continuity.providers) {
11911
+ if (provider.status !== "included") {
11912
+ console.log(` Excluded for model continuity: ${provider.provider} (${provider.fromModels.join("/") || "?"} -> ${provider.toModels.join("/") || "?"}; ${provider.status.replace("-", " ")})`);
11913
+ }
11914
+ }
11915
+ }
11844
11916
  function citedCell(c) {
11845
11917
  return `${c.cited}/${c.total}`;
11846
11918
  }
@@ -11932,6 +12004,7 @@ function printVisibilityStats(data) {
11932
12004
 
11933
12005
  // src/cli-commands/visibility-stats.ts
11934
12006
  var USAGE4 = "canonry visibility-stats <project> [--since <iso>] [--until <iso>] [--month <YYYY-MM>] [--last-runs <n>] [--by-provider] [--share-of-voice] [--format json|jsonl]";
12007
+ var COMPARE_USAGE = "canonry visibility-compare <project> --from <YYYY-MM> --to <YYYY-MM> [--format json]";
11935
12008
  var VISIBILITY_STATS_CLI_COMMANDS = [
11936
12009
  {
11937
12010
  path: ["visibility-stats"],
@@ -11960,6 +12033,22 @@ var VISIBILITY_STATS_CLI_COMMANDS = [
11960
12033
  format: input.format
11961
12034
  });
11962
12035
  }
12036
+ },
12037
+ {
12038
+ path: ["visibility-compare"],
12039
+ usage: COMPARE_USAGE,
12040
+ options: {
12041
+ from: stringOption(),
12042
+ to: stringOption()
12043
+ },
12044
+ run: async (input) => {
12045
+ const project = requireProject(input, "visibility-compare", COMPARE_USAGE);
12046
+ await showVisibilityCompare(project, {
12047
+ from: getString(input.values, "from"),
12048
+ to: getString(input.values, "to"),
12049
+ format: input.format
12050
+ });
12051
+ }
11963
12052
  }
11964
12053
  ];
11965
12054
 
package/dist/index.js CHANGED
@@ -1,11 +1,11 @@
1
1
  import {
2
2
  createServer
3
- } from "./chunk-GV665WOU.js";
3
+ } from "./chunk-NY7SC4ES.js";
4
4
  import {
5
5
  loadConfig
6
- } from "./chunk-RVH6QPTA.js";
7
- import "./chunk-WEAXJ25Y.js";
8
- import "./chunk-IQPMK36Y.js";
6
+ } from "./chunk-BMBHUFMI.js";
7
+ import "./chunk-V4SW7SVX.js";
8
+ import "./chunk-IAJ5TQ4S.js";
9
9
  export {
10
10
  createServer,
11
11
  loadConfig
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  IntelligenceService
3
- } from "./chunk-WEAXJ25Y.js";
4
- import "./chunk-IQPMK36Y.js";
3
+ } from "./chunk-V4SW7SVX.js";
4
+ import "./chunk-IAJ5TQ4S.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-RVH6QPTA.js";
6
+ } from "./chunk-BMBHUFMI.js";
7
7
  import {
8
8
  isReadOnlyKey
9
- } from "./chunk-IQPMK36Y.js";
9
+ } from "./chunk-IAJ5TQ4S.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.116.0",
3
+ "version": "4.117.1",
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",
@@ -65,27 +65,27 @@
65
65
  "@types/node-cron": "^3.0.11",
66
66
  "tsup": "^8.5.1",
67
67
  "tsx": "^4.19.0",
68
+ "@ainyc/canonry-config": "0.0.0",
68
69
  "@ainyc/canonry-api-client": "0.0.0",
69
70
  "@ainyc/canonry-api-routes": "0.0.0",
70
- "@ainyc/canonry-config": "0.0.0",
71
- "@ainyc/canonry-contracts": "0.0.0",
72
71
  "@ainyc/canonry-db": "0.0.0",
73
- "@ainyc/canonry-integration-cloud-run": "0.0.0",
72
+ "@ainyc/canonry-contracts": "0.0.0",
74
73
  "@ainyc/canonry-integration-bing": "0.0.0",
75
74
  "@ainyc/canonry-integration-openai-ads": "0.0.0",
76
- "@ainyc/canonry-integration-google": "0.0.0",
75
+ "@ainyc/canonry-integration-cloud-run": "0.0.0",
77
76
  "@ainyc/canonry-integration-commoncrawl": "0.0.0",
77
+ "@ainyc/canonry-integration-google": "0.0.0",
78
78
  "@ainyc/canonry-integration-google-business-profile": "0.0.0",
79
- "@ainyc/canonry-integration-traffic": "0.0.0",
80
79
  "@ainyc/canonry-integration-wordpress": "0.0.0",
80
+ "@ainyc/canonry-integration-traffic": "0.0.0",
81
81
  "@ainyc/canonry-intelligence": "0.0.0",
82
- "@ainyc/canonry-integration-google-places": "0.0.0",
83
82
  "@ainyc/canonry-provider-cdp": "0.0.0",
83
+ "@ainyc/canonry-integration-google-places": "0.0.0",
84
84
  "@ainyc/canonry-provider-claude": "0.0.0",
85
- "@ainyc/canonry-provider-openai": "0.0.0",
86
- "@ainyc/canonry-provider-perplexity": "0.0.0",
87
85
  "@ainyc/canonry-provider-gemini": "0.0.0",
88
- "@ainyc/canonry-provider-local": "0.0.0"
86
+ "@ainyc/canonry-provider-openai": "0.0.0",
87
+ "@ainyc/canonry-provider-local": "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",