@ainyc/canonry 4.180.8 → 4.182.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 (36) hide show
  1. package/README.md +77 -46
  2. package/assets/assets/{AuditHistoryPanel-qiuqNGvG.js → AuditHistoryPanel-1_FHpzj-.js} +1 -1
  3. package/assets/assets/{BacklinksPage-D-g5f0Xv.js → BacklinksPage-045za10_.js} +1 -1
  4. package/assets/assets/{ChartPrimitives-DG35TyhH.js → ChartPrimitives-DLEICrrL.js} +1 -1
  5. package/assets/assets/{HistoryPage-q8_pCuOs.js → HistoryPage-36K_6asu.js} +1 -1
  6. package/assets/assets/{MeasurementPropertyPage-C_wMjUZe.js → MeasurementPropertyPage-B4DJGoY6.js} +1 -1
  7. package/assets/assets/ProjectPage-CshC68Ne.js +9 -0
  8. package/assets/assets/{RunRow-D5hatdlY.js → RunRow-U2CN755e.js} +1 -1
  9. package/assets/assets/{RunsPage-Bj2snMM3.js → RunsPage-D0CtU4d-.js} +1 -1
  10. package/assets/assets/{SettingsPage-Cf5YgyJv.js → SettingsPage-zMWieTPK.js} +1 -1
  11. package/assets/assets/{SiteHealthSection-D8RLvMAE.js → SiteHealthSection-TpQPu_Uj.js} +3 -3
  12. package/assets/assets/{TrafficPage-CotJ14le.js → TrafficPage-DfLUt-64.js} +1 -1
  13. package/assets/assets/{TrafficSourceDetailPage-BcxYX-uq.js → TrafficSourceDetailPage-DbjNNWSt.js} +1 -1
  14. package/assets/assets/extract-error-message-CWqz1QPC.js +1 -0
  15. package/assets/assets/index-Brb7M_6G.js +86 -0
  16. package/assets/assets/{index-DXCQf5s1.css → index-DwdK2e4e.css} +1 -1
  17. package/assets/assets/{react-sigma_core.esm.min-DxZINEmi.js → react-sigma_core.esm.min-Drqprr9L.js} +1 -1
  18. package/assets/assets/{vendor-lucide-nYKv-BB7.js → vendor-lucide-XjCNFK0x.js} +1 -1
  19. package/assets/assets/{vendor-markdown-Bn7fRwrx.js → vendor-markdown-9tTeP8v7.js} +1 -1
  20. package/assets/assets/{vendor-radix-4UOaVWza.js → vendor-radix-BpmvLvpp.js} +1 -1
  21. package/assets/assets/{vendor-recharts-D8rt5lKn.js → vendor-recharts-FA0uySU7.js} +1 -1
  22. package/assets/assets/{vendor-tanstack-Dock0eH1.js → vendor-tanstack-CYBjbqVr.js} +1 -1
  23. package/assets/index.html +7 -7
  24. package/dist/{chunk-GFVZOVG3.js → chunk-BDJT7XZL.js} +68 -4
  25. package/dist/{chunk-GN2G7VFK.js → chunk-DY5ZDKQW.js} +159 -0
  26. package/dist/{chunk-IM4HFNGF.js → chunk-FVC7PGYQ.js} +41 -1
  27. package/dist/{chunk-G7M2KM7Q.js → chunk-I3KSOMJA.js} +2 -2
  28. package/dist/{chunk-ZJ2VGTYU.js → chunk-K45YKXE4.js} +4272 -3387
  29. package/dist/cli.js +141 -8
  30. package/dist/index.js +4 -4
  31. package/dist/{intelligence-service-IURLYRB3.js → intelligence-service-HGA553GT.js} +2 -2
  32. package/dist/mcp.js +3 -3
  33. package/package.json +10 -10
  34. package/assets/assets/ProjectPage-33THfDtC.js +0 -9
  35. package/assets/assets/extract-error-message-Bxt42scd.js +0 -1
  36. package/assets/assets/index-BlILyZJ5.js +0 -86
package/dist/cli.js CHANGED
@@ -28,11 +28,11 @@ import {
28
28
  trackCliCommandFinished,
29
29
  trackEvent,
30
30
  waitForServerRuntimeStartup
31
- } from "./chunk-GFVZOVG3.js";
31
+ } from "./chunk-BDJT7XZL.js";
32
32
  import {
33
33
  autoSyncSkills,
34
34
  formatAutoSyncNotice
35
- } from "./chunk-G7M2KM7Q.js";
35
+ } from "./chunk-I3KSOMJA.js";
36
36
  import {
37
37
  CliError,
38
38
  EXIT_SYSTEM_ERROR,
@@ -57,7 +57,7 @@ import {
57
57
  saveConfigPatch,
58
58
  systemError,
59
59
  usageError
60
- } from "./chunk-IM4HFNGF.js";
60
+ } from "./chunk-FVC7PGYQ.js";
61
61
  import {
62
62
  CLOUDFLARE_WORKER_BINDINGS,
63
63
  CLOUDFLARE_WORKER_GENERATED_MARKER,
@@ -71,7 +71,7 @@ import {
71
71
  projects,
72
72
  queries,
73
73
  renderReportHtml
74
- } from "./chunk-ZJ2VGTYU.js";
74
+ } from "./chunk-K45YKXE4.js";
75
75
  import {
76
76
  AdsDeliverySnapshotStatuses,
77
77
  AdsHistoricalCampaignRollupStatuses,
@@ -140,7 +140,7 @@ import {
140
140
  providerQuotaPolicySchema,
141
141
  resolveProviderInput,
142
142
  winnabilityClassSchema
143
- } from "./chunk-GN2G7VFK.js";
143
+ } from "./chunk-DY5ZDKQW.js";
144
144
 
145
145
  // src/cli.ts
146
146
  import { pathToFileURL } from "url";
@@ -7569,8 +7569,95 @@ async function listCompetitors(project, format) {
7569
7569
  console.log(` ${c.domain}`);
7570
7570
  }
7571
7571
  }
7572
+ async function showCompetitorLandscape(project, options) {
7573
+ const client = getClient10();
7574
+ const data = await client.getCompetitorLandscape(project, {
7575
+ window: options.window,
7576
+ scope: options.scope,
7577
+ groupKey: options.groupKey,
7578
+ provider: options.provider,
7579
+ ...options.groupBy ? { groupBy: options.groupBy } : {},
7580
+ ...options.model !== void 0 ? { model: options.model } : {},
7581
+ queryClass: options.queryClass,
7582
+ location: options.location,
7583
+ runId: options.runId
7584
+ });
7585
+ if (options.format === "json") {
7586
+ console.log(JSON.stringify(data, null, 2));
7587
+ return;
7588
+ }
7589
+ if (options.format === "jsonl") {
7590
+ console.log(JSON.stringify(data));
7591
+ return;
7592
+ }
7593
+ printCompetitorLandscape(data);
7594
+ }
7595
+ function printCompetitorLandscape(data) {
7596
+ const scope = data.scope.kind === "group" ? `market ${data.scope.groupKey}` : data.scope.kind === "all-markets" ? "all markets" : "project";
7597
+ console.log(`Competitor landscape \xB7 ${scope} \xB7 ${data.window}`);
7598
+ if (data.filters.model !== void 0) {
7599
+ console.log(`Requested model filter: ${data.filters.provider} \xB7 ${data.filters.model}`);
7600
+ }
7601
+ console.log("Mention share is answer-text evidence; citations are independent source-list evidence.");
7602
+ console.log(
7603
+ data.filters.queryClass === "all" ? "Share of voice is blank: branded and non-brand queries are pooled here. Add --query-class non-brand for a ratio." : `Counting ${data.filters.queryClass} queries only.`
7604
+ );
7605
+ if (data.truncated) console.log("Top 100 observed competitors and top 100 other cited sources shown; pinned competitors are complete.");
7606
+ console.log("");
7607
+ printLandscapeRows("Your brand", [data.project]);
7608
+ printLandscapeRows("Pinned competitors", data.pinned);
7609
+ printLandscapeRows("Observed competitors", data.observed);
7610
+ printLandscapeRows("Other cited sources", data.otherSources);
7611
+ console.log("");
7612
+ console.log(
7613
+ `Evidence: ${data.evidence.answeredResults} answer-text result(s), ${data.evidence.sourceResults} source result(s); excluded: ${data.evidence.excludedProbeResults} probe, ${data.evidence.excludedNonCompletedResults} non-completed.`
7614
+ );
7615
+ if (data.modelComparison) printModelComparison(data.modelComparison);
7616
+ }
7617
+ function describeServedModels(evidence) {
7618
+ if (evidence.status === "unknown") return "Unknown (not disclosed)";
7619
+ if (evidence.status === "known") return evidence.model;
7620
+ return [...evidence.models, ...evidence.includesUnknown ? ["Unknown (not disclosed)"] : []].join(", ");
7621
+ }
7622
+ function printModelComparison(comparison) {
7623
+ console.log("");
7624
+ console.log(`Model comparison \xB7 requested-model basis \xB7 ${comparison.groups.length} of ${comparison.totalGroups} groups`);
7625
+ console.log("Groups use stored observations. They do not form a matched-query or equal-weight comparison.");
7626
+ if (comparison.truncated) console.log("The first 50 provider/model groups are shown. Additional groups are omitted.");
7627
+ for (const group of comparison.groups) {
7628
+ console.log("");
7629
+ console.log(`${group.provider} \xB7 requested model: ${group.model ?? "Unknown (not recorded)"}`);
7630
+ console.log(`Served model evidence: ${describeServedModels(group.servedModels)}`);
7631
+ console.log(`Samples: ${group.snapshotCount} snapshot(s), ${group.evidence.answeredResults} answer-text result(s), ${group.evidence.sourceResults} source result(s).`);
7632
+ printLandscapeRows("Your brand", [group.project], true);
7633
+ printLandscapeRows("Pinned competitors", group.pinned, true);
7634
+ printLandscapeRows("Observed competitors", group.observed, true);
7635
+ printLandscapeRows("Other cited sources", group.otherSources, true);
7636
+ if (group.truncated) console.log("Top 100 observed competitors and top 100 other sources shown. Pinned competitors are complete.");
7637
+ }
7638
+ }
7639
+ function printLandscapeRows(heading, rows, showSampleCount = false) {
7640
+ console.log(`${heading}:`);
7641
+ if (rows.length === 0) {
7642
+ console.log(" \u2014");
7643
+ return;
7644
+ }
7645
+ for (const row of rows) {
7646
+ const sov = row.shareOfVoice === null ? "\u2014" : `${row.shareOfVoice.toFixed(1)}%`;
7647
+ console.log(` ${row.domain} mention ${row.mentionCount} \xB7 citation ${row.citationCount} \xB7 SOV ${sov}${showSampleCount ? ` \xB7 answers ${row.answeredResults}` : ""}`);
7648
+ }
7649
+ }
7572
7650
 
7573
7651
  // src/cli-commands/competitor.ts
7652
+ var LANDSCAPE_USAGE = "canonry competitor landscape <project> [--window 7d|30d|90d|all] [--group-key <key>|--scope all-markets] [--by-model] [--provider <provider> [--model <id>]] [--query-class all|branded|non-brand] [--location <label>] [--run-id <id>] [--format json|jsonl]";
7653
+ function parseLandscapeScope(value) {
7654
+ if (value === void 0 || value === "") return void 0;
7655
+ if (value !== "all-markets") throw usageError(`--scope must be "all-markets" (got "${value}")`, {
7656
+ message: '--scope must be "all-markets"',
7657
+ details: { command: "competitor.landscape", usage: LANDSCAPE_USAGE }
7658
+ });
7659
+ return value;
7660
+ }
7574
7661
  var COMPETITOR_CLI_COMMANDS = [
7575
7662
  {
7576
7663
  path: ["competitor", "add"],
@@ -7634,14 +7721,60 @@ var COMPETITOR_CLI_COMMANDS = [
7634
7721
  await listCompetitors(project, input.format);
7635
7722
  }
7636
7723
  },
7724
+ {
7725
+ path: ["competitor", "landscape"],
7726
+ usage: LANDSCAPE_USAGE,
7727
+ options: {
7728
+ window: stringOption(),
7729
+ "group-key": stringOption(),
7730
+ scope: stringOption(),
7731
+ provider: stringOption(),
7732
+ "by-model": { type: "boolean" },
7733
+ model: stringOption(),
7734
+ "query-class": stringOption(),
7735
+ location: stringOption(),
7736
+ "run-id": stringOption()
7737
+ },
7738
+ run: async (input) => {
7739
+ const project = requireProject(input, "competitor.landscape", LANDSCAPE_USAGE);
7740
+ const scope = parseLandscapeScope(getString(input.values, "scope"));
7741
+ const groupKey = getString(input.values, "group-key");
7742
+ const provider = getString(input.values, "provider");
7743
+ const model = getString(input.values, "model");
7744
+ if (model !== void 0 && !provider?.trim()) {
7745
+ throw usageError("--model requires --provider", {
7746
+ message: "--model requires --provider",
7747
+ details: { command: "competitor.landscape", usage: LANDSCAPE_USAGE }
7748
+ });
7749
+ }
7750
+ if (scope === "all-markets" && groupKey) {
7751
+ throw usageError("--group-key cannot be combined with --scope all-markets", {
7752
+ message: "--group-key cannot be combined with --scope all-markets",
7753
+ details: { command: "competitor.landscape", usage: LANDSCAPE_USAGE }
7754
+ });
7755
+ }
7756
+ await showCompetitorLandscape(project, {
7757
+ window: getString(input.values, "window"),
7758
+ groupKey,
7759
+ scope,
7760
+ provider,
7761
+ ...getBoolean(input.values, "by-model") ? { groupBy: "model" } : {},
7762
+ ...model !== void 0 ? { model } : {},
7763
+ queryClass: getString(input.values, "query-class"),
7764
+ location: getString(input.values, "location"),
7765
+ runId: getString(input.values, "run-id"),
7766
+ format: input.format
7767
+ });
7768
+ }
7769
+ },
7637
7770
  {
7638
7771
  path: ["competitor"],
7639
- usage: "canonry competitor <add|remove|delete|list> <project> [args]",
7772
+ usage: "canonry competitor <add|remove|delete|list|landscape> <project> [args]",
7640
7773
  run: async (input) => {
7641
7774
  unknownSubcommand(input.positionals[0], {
7642
7775
  command: "competitor",
7643
- usage: "canonry competitor <add|remove|delete|list> <project> [args]",
7644
- available: ["add", "remove", "delete", "list"]
7776
+ usage: "canonry competitor <add|remove|delete|list|landscape> <project> [args]",
7777
+ available: ["add", "remove", "delete", "list", "landscape"]
7645
7778
  });
7646
7779
  }
7647
7780
  }
package/dist/index.js CHANGED
@@ -3,12 +3,12 @@ import {
3
3
  createGoogleMarketingCredentialStore,
4
4
  createGoogleMarketingRuntime,
5
5
  createServer
6
- } from "./chunk-GFVZOVG3.js";
6
+ } from "./chunk-BDJT7XZL.js";
7
7
  import {
8
8
  loadConfig
9
- } from "./chunk-IM4HFNGF.js";
10
- import "./chunk-ZJ2VGTYU.js";
11
- import "./chunk-GN2G7VFK.js";
9
+ } from "./chunk-FVC7PGYQ.js";
10
+ import "./chunk-K45YKXE4.js";
11
+ import "./chunk-DY5ZDKQW.js";
12
12
  export {
13
13
  GoogleMarketingRuntimeError,
14
14
  createGoogleMarketingCredentialStore,
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  IntelligenceService
3
- } from "./chunk-ZJ2VGTYU.js";
4
- import "./chunk-GN2G7VFK.js";
3
+ } from "./chunk-K45YKXE4.js";
4
+ import "./chunk-DY5ZDKQW.js";
5
5
  export {
6
6
  IntelligenceService
7
7
  };
package/dist/mcp.js CHANGED
@@ -1,13 +1,13 @@
1
1
  import {
2
2
  autoSyncSkills
3
- } from "./chunk-G7M2KM7Q.js";
3
+ } from "./chunk-I3KSOMJA.js";
4
4
  import {
5
5
  createApiClient,
6
6
  createCanonryMcpServer
7
- } from "./chunk-IM4HFNGF.js";
7
+ } from "./chunk-FVC7PGYQ.js";
8
8
  import {
9
9
  isReadOnlyKey
10
- } from "./chunk-GN2G7VFK.js";
10
+ } from "./chunk-DY5ZDKQW.js";
11
11
 
12
12
  // src/mcp/cli.ts
13
13
  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.180.8",
3
+ "version": "4.182.3",
4
4
  "type": "module",
5
5
  "description": "Self-hosted AI visibility (AEO) platform: track how ChatGPT, Claude, Gemini, and Perplexity cite your domain, join it with Search Console, GA4, server-side traffic, and paid media, and fix what you find through agent tools (CLI, REST, MCP). Local SQLite.",
6
6
  "license": "FSL-1.1-ALv2",
@@ -72,29 +72,29 @@
72
72
  "tsx": "^4.19.0",
73
73
  "@ainyc/canonry-api-client": "0.0.0",
74
74
  "@ainyc/canonry-api-routes": "0.0.0",
75
- "@ainyc/canonry-config": "0.0.0",
76
- "@ainyc/canonry-db": "0.0.0",
77
75
  "@ainyc/canonry-contracts": "0.0.0",
76
+ "@ainyc/canonry-db": "0.0.0",
77
+ "@ainyc/canonry-config": "0.0.0",
78
78
  "@ainyc/canonry-integration-bing": "0.0.0",
79
79
  "@ainyc/canonry-integration-cloud-run": "0.0.0",
80
80
  "@ainyc/canonry-integration-cloudflare-queue": "0.0.0",
81
81
  "@ainyc/canonry-integration-cloudflare-worker": "0.0.0",
82
- "@ainyc/canonry-integration-commoncrawl": "0.0.0",
83
82
  "@ainyc/canonry-integration-google": "0.0.0",
84
- "@ainyc/canonry-integration-google-places": "0.0.0",
85
83
  "@ainyc/canonry-integration-google-ads": "0.0.0",
86
- "@ainyc/canonry-integration-google-tag-manager": "0.0.0",
87
- "@ainyc/canonry-integration-wordpress": "0.0.0",
88
- "@ainyc/canonry-integration-openai-ads": "0.0.0",
89
84
  "@ainyc/canonry-integration-google-business-profile": "0.0.0",
85
+ "@ainyc/canonry-integration-google-places": "0.0.0",
86
+ "@ainyc/canonry-integration-commoncrawl": "0.0.0",
87
+ "@ainyc/canonry-integration-openai-ads": "0.0.0",
88
+ "@ainyc/canonry-integration-google-tag-manager": "0.0.0",
90
89
  "@ainyc/canonry-integration-traffic": "0.0.0",
91
90
  "@ainyc/canonry-intelligence": "0.0.0",
92
91
  "@ainyc/canonry-provider-cdp": "0.0.0",
92
+ "@ainyc/canonry-integration-wordpress": "0.0.0",
93
93
  "@ainyc/canonry-provider-claude": "0.0.0",
94
94
  "@ainyc/canonry-provider-gemini": "0.0.0",
95
95
  "@ainyc/canonry-provider-local": "0.0.0",
96
- "@ainyc/canonry-provider-perplexity": "0.0.0",
97
- "@ainyc/canonry-provider-openai": "0.0.0"
96
+ "@ainyc/canonry-provider-openai": "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",