@canonry/canonry 5.20.3 → 5.20.4

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.
@@ -9286,9 +9286,11 @@ function buildMentionShare(snapshots, options) {
9286
9286
  if (text2.length === 0) continue;
9287
9287
  tally.snapshotsWithAnswerText++;
9288
9288
  if (snap.projectMentioned) tally.projectMentionSnapshots++;
9289
+ if (options.competitors.length === 0) continue;
9290
+ const prepared = prepareBrandMatchText(text2);
9289
9291
  for (const competitor of options.competitors) {
9290
9292
  const matcher = competitorMatchers.get(competitor.domain);
9291
- if (matcher && matcherMatchesText(matcher, text2)) {
9293
+ if (matcher && matcherMatchesText(matcher, prepared)) {
9292
9294
  tally.competitorCounts.set(competitor.domain, (tally.competitorCounts.get(competitor.domain) ?? 0) + 1);
9293
9295
  }
9294
9296
  }
@@ -34885,13 +34887,21 @@ function metric(key, label, queryClass, driftRobust, from, to, continuityBlock)
34885
34887
  const rateRatio = from.point === null || from.point === 0 || to.point === null ? null : Math.round(to.point / from.point * 100) / 100;
34886
34888
  return { key, label, queryClass, driftRobust, from, to, rateRatio, direction, verdict };
34887
34889
  }
34888
- function countPeriod(snaps, competitors2, queryClassOf, classificationAvailable, projectBrandNames) {
34890
+ function modelEvidenceOf(snaps) {
34891
+ const evidence = /* @__PURE__ */ new Map();
34892
+ for (const snap of snaps) {
34893
+ const models = evidence.get(snap.provider) ?? [];
34894
+ models.push(snap.model);
34895
+ evidence.set(snap.provider, models);
34896
+ }
34897
+ return evidence;
34898
+ }
34899
+ function countPeriod(snaps, competitors2, queryClassOf, classificationAvailable, projectMatcher) {
34889
34900
  let checked = 0;
34890
34901
  let mentioned = 0;
34891
34902
  let cited = 0;
34892
34903
  let competitorCited = 0;
34893
34904
  const perProvider = /* @__PURE__ */ new Map();
34894
- const modelEvidence = /* @__PURE__ */ new Map();
34895
34905
  const mentionedQueries = /* @__PURE__ */ new Set();
34896
34906
  const competitorHosts = competitors2.map((c) => hostOf(c.domain)).filter((h) => h !== null && h.length > 0);
34897
34907
  for (const snap of snaps) {
@@ -34908,9 +34918,6 @@ function countPeriod(snaps, competitors2, queryClassOf, classificationAvailable,
34908
34918
  if (isMentioned) pp.mentioned += 1;
34909
34919
  if (isCited) pp.cited += 1;
34910
34920
  perProvider.set(snap.provider, pp);
34911
- const models = modelEvidence.get(snap.provider) ?? [];
34912
- models.push(snap.model);
34913
- modelEvidence.set(snap.provider, models);
34914
34921
  if (competitorHosts.length > 0 && snap.citedDomains.length > 0) {
34915
34922
  const citedHosts = snap.citedDomains.map((d) => hostOf(d)).filter((h) => h !== null && h.length > 0);
34916
34923
  for (const compHost of competitorHosts) {
@@ -34922,7 +34929,7 @@ function countPeriod(snaps, competitors2, queryClassOf, classificationAvailable,
34922
34929
  snaps.map((s) => ({
34923
34930
  // Share uses current identity; named-rate counts above deliberately keep
34924
34931
  // their historical persisted-boolean semantics.
34925
- projectMentioned: s.answerText ? determineAnswerMentioned(s.answerText, [...projectBrandNames], []) : s.answerMentioned === true,
34932
+ projectMentioned: s.answerText ? matcherMatchesText(projectMatcher, s.answerText) : s.answerMentioned === true,
34926
34933
  answerText: s.answerText,
34927
34934
  queryClass: queryClassOf(s)
34928
34935
  })),
@@ -34937,7 +34944,6 @@ function countPeriod(snaps, competitors2, queryClassOf, classificationAvailable,
34937
34944
  competitorCited,
34938
34945
  queriesMentioned: mentionedQueries.size,
34939
34946
  perProvider,
34940
- modelEvidence,
34941
34947
  mentionShare,
34942
34948
  competitors: mentionShare.breakdown.perCompetitor.map((c) => ({ domain: c.domain, mentions: c.mentionSnapshots }))
34943
34949
  };
@@ -34956,6 +34962,7 @@ function computeVisibilityCompare(input) {
34956
34962
  const classificationAvailable = classifier !== null;
34957
34963
  const queryTextById = new Map(input.queries.map((q) => [q.id, q.query]));
34958
34964
  const queryClassOf = (snap) => classifier ? classifier.classify(queryTextById.get(snap.queryId) ?? snap.queryText) : null;
34965
+ const projectMatcher = compileBrandAliases(input.brandNames ?? []);
34959
34966
  const fromObs = observed(input.from.snapshots, attribution);
34960
34967
  const toObs = observed(input.to.snapshots, attribution);
34961
34968
  const queriesObservedBoth = new Set([...fromObs.queryIds].filter((q) => toObs.queryIds.has(q)));
@@ -34963,13 +34970,11 @@ function computeVisibilityCompare(input) {
34963
34970
  const toPairs = observedPairs(input.to.snapshots, attribution, queriesObservedBoth);
34964
34971
  const pairsBoth = new Map([...fromPairs].filter(([key]) => toPairs.has(key)));
34965
34972
  const candidateProviders = new Set([...pairsBoth.values()].map((pair) => pair.provider));
34966
- const fromCandidateSnaps = restrict(input.from.snapshots, attribution, pairsBoth);
34967
- const toCandidateSnaps = restrict(input.to.snapshots, attribution, pairsBoth);
34968
- const fromCandidateCounts = countPeriod(fromCandidateSnaps, input.competitors, queryClassOf, classificationAvailable, input.brandNames ?? []);
34969
- const toCandidateCounts = countPeriod(toCandidateSnaps, input.competitors, queryClassOf, classificationAvailable, input.brandNames ?? []);
34973
+ const fromCandidateModels = modelEvidenceOf(restrict(input.from.snapshots, attribution, pairsBoth));
34974
+ const toCandidateModels = modelEvidenceOf(restrict(input.to.snapshots, attribution, pairsBoth));
34970
34975
  const continuityProviders = [...candidateProviders].sort((a, b) => a.localeCompare(b)).map((provider) => {
34971
- const fromEvidence = classifyModelEvidence(fromCandidateCounts.modelEvidence.get(provider) ?? []);
34972
- const toEvidence = classifyModelEvidence(toCandidateCounts.modelEvidence.get(provider) ?? []);
34976
+ const fromEvidence = classifyModelEvidence(fromCandidateModels.get(provider) ?? []);
34977
+ const toEvidence = classifyModelEvidence(toCandidateModels.get(provider) ?? []);
34973
34978
  const fromModels = modelIds(fromEvidence);
34974
34979
  const toModels = modelIds(toEvidence);
34975
34980
  const status = isUnknownModelEvidence(fromEvidence) || isUnknownModelEvidence(toEvidence) ? "model-unknown" : fromEvidence.status === "known" && toEvidence.status === "known" && fromEvidence.model === toEvidence.model ? "included" : "model-discontinuous";
@@ -34985,8 +34990,8 @@ function computeVisibilityCompare(input) {
34985
34990
  const excludedProviders = [.../* @__PURE__ */ new Set([...fromObs.providers, ...toObs.providers])].filter((p) => !providersBoth.has(p)).sort((a, b) => a.localeCompare(b));
34986
34991
  const fromSnaps = restrict(input.from.snapshots, attribution, comparedPairs);
34987
34992
  const toSnaps = restrict(input.to.snapshots, attribution, comparedPairs);
34988
- const fromCounts = countPeriod(fromSnaps, input.competitors, queryClassOf, classificationAvailable, input.brandNames ?? []);
34989
- const toCounts = countPeriod(toSnaps, input.competitors, queryClassOf, classificationAvailable, input.brandNames ?? []);
34993
+ const fromCounts = countPeriod(fromSnaps, input.competitors, queryClassOf, classificationAvailable, projectMatcher);
34994
+ const toCounts = countPeriod(toSnaps, input.competitors, queryClassOf, classificationAvailable, projectMatcher);
34990
34995
  const shareCounts = (c) => ({
34991
34996
  proj: c.mentionShare.breakdown.projectMentionSnapshots,
34992
34997
  comp: c.mentionShare.breakdown.competitorMentionSnapshots
@@ -35037,8 +35042,8 @@ function computeVisibilityCompare(input) {
35037
35042
  )
35038
35043
  ];
35039
35044
  const modelChanges = [...candidateProviders].sort((a, b) => a.localeCompare(b)).map((provider) => {
35040
- const fromModels = modelIds(classifyModelEvidence(fromCandidateCounts.modelEvidence.get(provider) ?? []));
35041
- const toModels = modelIds(classifyModelEvidence(toCandidateCounts.modelEvidence.get(provider) ?? []));
35045
+ const fromModels = modelIds(classifyModelEvidence(fromCandidateModels.get(provider) ?? []));
35046
+ const toModels = modelIds(classifyModelEvidence(toCandidateModels.get(provider) ?? []));
35042
35047
  return { provider, fromModels, toModels };
35043
35048
  }).filter(
35044
35049
  (c) => c.fromModels.length > 0 && c.toModels.length > 0 && JSON.stringify(c.fromModels) !== JSON.stringify(c.toModels)
@@ -48037,6 +48042,8 @@ async function googleRoutes(app, opts) {
48037
48042
  tx.delete(gbpKeywordMonthly).where(eq46(gbpKeywordMonthly.projectId, projectId)).run();
48038
48043
  tx.delete(gbpPlaceActions).where(eq46(gbpPlaceActions.projectId, projectId)).run();
48039
48044
  tx.delete(gbpLodgingSnapshots).where(eq46(gbpLodgingSnapshots.projectId, projectId)).run();
48045
+ tx.delete(gbpAttributesSnapshots).where(eq46(gbpAttributesSnapshots.projectId, projectId)).run();
48046
+ tx.delete(gbpPlaceDetails).where(eq46(gbpPlaceDetails.projectId, projectId)).run();
48040
48047
  tx.delete(gbpLocations).where(eq46(gbpLocations.projectId, projectId)).run();
48041
48048
  }
48042
48049
  function currentProjectAccount(projectId) {
@@ -18,7 +18,7 @@ import {
18
18
  deleteSiteCrawlGraphLayout,
19
19
  persistSiteCrawlGraphLayout,
20
20
  prepareSiteCrawlGraphLayout
21
- } from "./chunk-KHNPBUUN.js";
21
+ } from "./chunk-TWLJRAWA.js";
22
22
  import {
23
23
  CanonryMcpToolNames,
24
24
  CliError,
@@ -186,7 +186,7 @@ import {
186
186
  siteLivenessState,
187
187
  toAlertView,
188
188
  usageCounters
189
- } from "./chunk-7YGOE4R2.js";
189
+ } from "./chunk-NSKFW3NF.js";
190
190
  import {
191
191
  AGENT_MEMORY_VALUE_MAX_BYTES,
192
192
  AGENT_NONE,
@@ -6648,7 +6648,7 @@ function nonBlank(value) {
6648
6648
  return trimmed ? trimmed : void 0;
6649
6649
  }
6650
6650
  function resolveBuildCommit(env = process.env) {
6651
- const embedded = true ? "391e3197a54a3b85226958ac923a021d124eaf60" : void 0;
6651
+ const embedded = true ? "c87b5bdf06eeeab4fafa7742f07c1c91149c0b70" : void 0;
6652
6652
  return nonBlank(embedded) ?? nonBlank(env.CANONRY_COMMIT);
6653
6653
  }
6654
6654
  function resolveInstanceIdentity(env = process.env) {
@@ -12235,7 +12235,7 @@ function readStoredGroundingSources(rawResponse) {
12235
12235
  return result2;
12236
12236
  }
12237
12237
  async function backfillInsightsCommand(project, opts) {
12238
- const { IntelligenceService: IntelligenceService2 } = await import("./intelligence-service-H4LGPJLZ.js");
12238
+ const { IntelligenceService: IntelligenceService2 } = await import("./intelligence-service-QHSR2H7F.js");
12239
12239
  const config = loadConfig();
12240
12240
  const db = createClient(config.database);
12241
12241
  migrate(db);
@@ -5,7 +5,7 @@ import {
5
5
  siteCrawlGraphNodes,
6
6
  siteCrawlPages,
7
7
  siteCrawlSnapshots
8
- } from "./chunk-7YGOE4R2.js";
8
+ } from "./chunk-NSKFW3NF.js";
9
9
  import {
10
10
  SITE_CRAWL_GRAPH_MAX_EDGES,
11
11
  SITE_CRAWL_GRAPH_MAX_NODES,
package/dist/cli.js CHANGED
@@ -35,7 +35,7 @@ import {
35
35
  trackCliCommandFinished,
36
36
  trackEvent,
37
37
  waitForServerRuntimeStartup
38
- } from "./chunk-H6XSHOS5.js";
38
+ } from "./chunk-P73YBGZP.js";
39
39
  import {
40
40
  autoSyncSkills,
41
41
  formatAutoSyncNotice
@@ -62,7 +62,7 @@ import {
62
62
  trustedProxiesProblem,
63
63
  trustedProxyProblem
64
64
  } from "./chunk-RB2F4D3Z.js";
65
- import "./chunk-KHNPBUUN.js";
65
+ import "./chunk-TWLJRAWA.js";
66
66
  import {
67
67
  CliError,
68
68
  EXIT_SYSTEM_ERROR,
@@ -89,7 +89,7 @@ import {
89
89
  queries,
90
90
  renderReportHtml,
91
91
  runs
92
- } from "./chunk-7YGOE4R2.js";
92
+ } from "./chunk-NSKFW3NF.js";
93
93
  import {
94
94
  AdsDeliverySnapshotStatuses,
95
95
  AdsHistoricalCampaignRollupStatuses,
@@ -442,7 +442,7 @@ function parseDemoTrustedProxies(values) {
442
442
  async function demoCommand(options) {
443
443
  const { host, port } = parseDemoListenOptions(options);
444
444
  const trustProxy = parseDemoTrustedProxies(options.trustProxy);
445
- const { createDemoServer } = await import("./demo-server-JYDAUEP2.js");
445
+ const { createDemoServer } = await import("./demo-server-FH2K6TCD.js");
446
446
  const app = await createDemoServer({ trustProxy });
447
447
  let stopping = false;
448
448
  const stop = () => {
@@ -4,7 +4,7 @@ import {
4
4
  import {
5
5
  layoutSiteCrawlGraphInput,
6
6
  persistSiteCrawlGraphLayout
7
- } from "./chunk-KHNPBUUN.js";
7
+ } from "./chunk-TWLJRAWA.js";
8
8
  import {
9
9
  PACKAGE_VERSION,
10
10
  canonryMcpTools
@@ -84,7 +84,7 @@ import {
84
84
  siteCrawlPages,
85
85
  siteCrawlSnapshots,
86
86
  trafficSources
87
- } from "./chunk-7YGOE4R2.js";
87
+ } from "./chunk-NSKFW3NF.js";
88
88
  import {
89
89
  RunKinds,
90
90
  SiteCrawlFetchStates,
package/dist/index.js CHANGED
@@ -3,13 +3,13 @@ import {
3
3
  createGoogleMarketingCredentialStore,
4
4
  createGoogleMarketingRuntime,
5
5
  createServer
6
- } from "./chunk-H6XSHOS5.js";
6
+ } from "./chunk-P73YBGZP.js";
7
7
  import {
8
8
  loadConfig
9
9
  } from "./chunk-PXVJ3P5G.js";
10
- import "./chunk-KHNPBUUN.js";
10
+ import "./chunk-TWLJRAWA.js";
11
11
  import "./chunk-JJPZ4OQ2.js";
12
- import "./chunk-7YGOE4R2.js";
12
+ import "./chunk-NSKFW3NF.js";
13
13
  import "./chunk-TOSPZ7I5.js";
14
14
  export {
15
15
  GoogleMarketingRuntimeError,
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  HISTORY_WINDOW_RUNS,
3
3
  IntelligenceService
4
- } from "./chunk-7YGOE4R2.js";
4
+ } from "./chunk-NSKFW3NF.js";
5
5
  import "./chunk-TOSPZ7I5.js";
6
6
  export {
7
7
  HISTORY_WINDOW_RUNS,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@canonry/canonry",
3
- "version": "5.20.3",
3
+ "version": "5.20.4",
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
  "keywords": [
@@ -86,32 +86,32 @@
86
86
  "@types/node-cron": "^3.0.11",
87
87
  "tsup": "^8.5.1",
88
88
  "tsx": "^4.19.0",
89
- "@ainyc/canonry-api-client": "0.0.0",
90
- "@ainyc/canonry-config": "0.0.0",
91
89
  "@ainyc/canonry-web": "0.0.0",
90
+ "@ainyc/canonry-api-client": "0.0.0",
92
91
  "@ainyc/canonry-api-routes": "0.0.0",
93
- "@ainyc/canonry-contracts": "0.0.0",
92
+ "@ainyc/canonry-config": "0.0.0",
94
93
  "@ainyc/canonry-db": "0.0.0",
94
+ "@ainyc/canonry-contracts": "0.0.0",
95
+ "@ainyc/canonry-integration-bing": "0.0.0",
95
96
  "@ainyc/canonry-integration-cloud-run": "0.0.0",
96
97
  "@ainyc/canonry-integration-cloudflare-worker": "0.0.0",
97
- "@ainyc/canonry-integration-bing": "0.0.0",
98
98
  "@ainyc/canonry-integration-google": "0.0.0",
99
- "@ainyc/canonry-integration-cloudflare-queue": "0.0.0",
100
99
  "@ainyc/canonry-integration-commoncrawl": "0.0.0",
100
+ "@ainyc/canonry-integration-cloudflare-queue": "0.0.0",
101
101
  "@ainyc/canonry-integration-google-ads": "0.0.0",
102
102
  "@ainyc/canonry-integration-google-places": "0.0.0",
103
- "@ainyc/canonry-integration-google-business-profile": "0.0.0",
104
103
  "@ainyc/canonry-integration-google-tag-manager": "0.0.0",
104
+ "@ainyc/canonry-integration-google-business-profile": "0.0.0",
105
105
  "@ainyc/canonry-integration-openai-ads": "0.0.0",
106
106
  "@ainyc/canonry-integration-traffic": "0.0.0",
107
- "@ainyc/canonry-integration-wordpress": "0.0.0",
108
107
  "@ainyc/canonry-intelligence": "0.0.0",
109
108
  "@ainyc/canonry-provider-cdp": "0.0.0",
110
- "@ainyc/canonry-provider-claude": "0.0.0",
111
- "@ainyc/canonry-provider-local": "0.0.0",
112
109
  "@ainyc/canonry-provider-gemini": "0.0.0",
110
+ "@ainyc/canonry-integration-wordpress": "0.0.0",
111
+ "@ainyc/canonry-provider-local": "0.0.0",
112
+ "@ainyc/canonry-provider-perplexity": "0.0.0",
113
113
  "@ainyc/canonry-provider-openai": "0.0.0",
114
- "@ainyc/canonry-provider-perplexity": "0.0.0"
114
+ "@ainyc/canonry-provider-claude": "0.0.0"
115
115
  },
116
116
  "scripts": {
117
117
  "build": "pnpm run build:cli && pnpm run build:web",