@ainyc/canonry 4.111.0 → 4.112.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/assets/{BacklinksPage-Ccp5dJm2.js → BacklinksPage-0OUPoMJf.js} +1 -1
  2. package/assets/assets/{ChartPrimitives-DZI_FVyX.js → ChartPrimitives-BeJemaLi.js} +1 -1
  3. package/assets/assets/ProjectPage-CD0RS8DR.js +7 -0
  4. package/assets/assets/{RunRow-CPf7aV1o.js → RunRow-CCnuv5wi.js} +1 -1
  5. package/assets/assets/{RunsPage-CI8AcUal.js → RunsPage-IqTj8i9c.js} +1 -1
  6. package/assets/assets/{SettingsPage-QI2X5EIb.js → SettingsPage-DKdvVPVp.js} +1 -1
  7. package/assets/assets/{TrafficPage-CcELR6n1.js → TrafficPage-xPENJ4Du.js} +1 -1
  8. package/assets/assets/{TrafficSourceDetailPage-C-9rc4ly.js → TrafficSourceDetailPage-CP6o754T.js} +1 -1
  9. package/assets/assets/{arrow-left-3WT6TImA.js → arrow-left-DGiw6bsJ.js} +1 -1
  10. package/assets/assets/{extract-error-message-43ehRbIG.js → extract-error-message-CYh3RHSN.js} +1 -1
  11. package/assets/assets/{index-BpnaXO_X.js → index-BpHZkgFH.js} +2 -2
  12. package/assets/assets/{index-JD5rv_sY.css → index-CD6LKwQu.css} +1 -1
  13. package/assets/assets/{trash-2-Dk-RvBpF.js → trash-2-DBeJW7Iw.js} +1 -1
  14. package/assets/index.html +2 -2
  15. package/dist/{chunk-Y26GYDS6.js → chunk-6M2ALGJA.js} +1 -1
  16. package/dist/{chunk-4TQOZJPF.js → chunk-KS2M7B5E.js} +8 -4
  17. package/dist/{chunk-CVXBE3ST.js → chunk-UOMNYP5T.js} +46 -6
  18. package/dist/{chunk-ZT7GVLS3.js → chunk-VICGMHY2.js} +1 -0
  19. package/dist/cli.js +6 -6
  20. package/dist/index.js +4 -4
  21. package/dist/{intelligence-service-4MQUT3OO.js → intelligence-service-RGOY43QR.js} +2 -2
  22. package/dist/mcp.js +2 -2
  23. package/package.json +12 -12
  24. package/assets/assets/ProjectPage-feeXXGgl.js +0 -7
@@ -1 +1 @@
1
- import{c}from"./index-BpnaXO_X.js";const a=[["circle",{cx:"12",cy:"12",r:"10",key:"1mglay"}],["path",{d:"m9 12 2 2 4-4",key:"dzmm74"}]],h=c("circle-check",a);const e=[["circle",{cx:"12",cy:"12",r:"10",key:"1mglay"}],["path",{d:"M9.09 9a3 3 0 0 1 5.83 1c0 2-3 3-3 3",key:"1u773s"}],["path",{d:"M12 17h.01",key:"p32p05"}]],n=c("circle-question-mark",e);const o=[["path",{d:"M12 15V3",key:"m9g1x1"}],["path",{d:"M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4",key:"ih7n3h"}],["path",{d:"m7 10 5 5 5-5",key:"brsn70"}]],s=c("download",o);const t=[["path",{d:"M10 11v6",key:"nco0om"}],["path",{d:"M14 11v6",key:"outv1u"}],["path",{d:"M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6",key:"miytrc"}],["path",{d:"M3 6h18",key:"d0wm0j"}],["path",{d:"M8 6V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2",key:"e791ji"}]],r=c("trash-2",t);export{h as C,s as D,r as T,n as a};
1
+ import{c}from"./index-BpHZkgFH.js";const a=[["circle",{cx:"12",cy:"12",r:"10",key:"1mglay"}],["path",{d:"m9 12 2 2 4-4",key:"dzmm74"}]],h=c("circle-check",a);const e=[["circle",{cx:"12",cy:"12",r:"10",key:"1mglay"}],["path",{d:"M9.09 9a3 3 0 0 1 5.83 1c0 2-3 3-3 3",key:"1u773s"}],["path",{d:"M12 17h.01",key:"p32p05"}]],n=c("circle-question-mark",e);const o=[["path",{d:"M12 15V3",key:"m9g1x1"}],["path",{d:"M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4",key:"ih7n3h"}],["path",{d:"m7 10 5 5 5-5",key:"brsn70"}]],s=c("download",o);const t=[["path",{d:"M10 11v6",key:"nco0om"}],["path",{d:"M14 11v6",key:"outv1u"}],["path",{d:"M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6",key:"miytrc"}],["path",{d:"M3 6h18",key:"d0wm0j"}],["path",{d:"M8 6V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2",key:"e791ji"}]],r=c("trash-2",t);export{h as C,s as D,r as T,n as a};
package/assets/index.html CHANGED
@@ -12,12 +12,12 @@
12
12
  <link rel="icon" type="image/png" sizes="32x32" href="./favicon-32.png" />
13
13
  <link rel="apple-touch-icon" href="./apple-touch-icon.png" />
14
14
  <title>Canonry</title>
15
- <script type="module" crossorigin src="./assets/index-BpnaXO_X.js"></script>
15
+ <script type="module" crossorigin src="./assets/index-BpHZkgFH.js"></script>
16
16
  <link rel="modulepreload" crossorigin href="./assets/vendor-tanstack-Be8JdV5M.js">
17
17
  <link rel="modulepreload" crossorigin href="./assets/vendor-radix-CQ77EO2y.js">
18
18
  <link rel="modulepreload" crossorigin href="./assets/vendor-recharts-C9EZkgbP.js">
19
19
  <link rel="modulepreload" crossorigin href="./assets/vendor-markdown-6dwjPOKK.js">
20
- <link rel="stylesheet" crossorigin href="./assets/index-JD5rv_sY.css">
20
+ <link rel="stylesheet" crossorigin href="./assets/index-CD6LKwQu.css">
21
21
  </head>
22
22
  <body>
23
23
  <div id="root"></div>
@@ -25,7 +25,7 @@ import {
25
25
  trafficConnectVercelRequestSchema,
26
26
  trafficConnectWordpressRequestSchema,
27
27
  trafficEventKindSchema
28
- } from "./chunk-ZT7GVLS3.js";
28
+ } from "./chunk-VICGMHY2.js";
29
29
 
30
30
  // src/config.ts
31
31
  import fs from "fs";
@@ -10,7 +10,7 @@ import {
10
10
  loadConfig,
11
11
  loadConfigRaw,
12
12
  saveConfigPatch
13
- } from "./chunk-Y26GYDS6.js";
13
+ } from "./chunk-6M2ALGJA.js";
14
14
  import {
15
15
  CC_CACHE_DIR,
16
16
  DUCKDB_SPEC,
@@ -115,7 +115,7 @@ import {
115
115
  siteAuditPages,
116
116
  siteAuditSnapshots,
117
117
  usageCounters
118
- } from "./chunk-CVXBE3ST.js";
118
+ } from "./chunk-UOMNYP5T.js";
119
119
  import {
120
120
  AGENT_MEMORY_VALUE_MAX_BYTES,
121
121
  AGENT_PROVIDER_IDS,
@@ -178,7 +178,7 @@ import {
178
178
  validationError,
179
179
  winnabilityClassLabel,
180
180
  withRetry
181
- } from "./chunk-ZT7GVLS3.js";
181
+ } from "./chunk-VICGMHY2.js";
182
182
 
183
183
  // src/telemetry.ts
184
184
  import crypto from "crypto";
@@ -5643,11 +5643,15 @@ function buildDefaultDeps(registry) {
5643
5643
  return { name, fromAnswer, fromGrounding };
5644
5644
  }));
5645
5645
  const candidates = perProvider.flatMap((r) => [...r.fromAnswer, ...r.fromGrounding]);
5646
+ const candidateProviders = perProvider.flatMap(
5647
+ (r) => [...r.fromAnswer, ...r.fromGrounding].map(() => r.name)
5648
+ );
5646
5649
  const providerCounts = Object.fromEntries(
5647
5650
  perProvider.map((r) => [r.name, r.fromAnswer.length + r.fromGrounding.length])
5648
5651
  );
5649
5652
  return {
5650
5653
  candidates,
5654
+ candidateProviders,
5651
5655
  provider: providerNames.join("+"),
5652
5656
  // Session diagnostics: the raw-candidate splits, persisted on
5653
5657
  // discovery_sessions so seed-quality calibration is measurable.
@@ -6504,7 +6508,7 @@ function readStoredGroundingSources(rawResponse) {
6504
6508
  return result;
6505
6509
  }
6506
6510
  async function backfillInsightsCommand(project, opts) {
6507
- const { IntelligenceService: IntelligenceService2 } = await import("./intelligence-service-4MQUT3OO.js");
6511
+ const { IntelligenceService: IntelligenceService2 } = await import("./intelligence-service-RGOY43QR.js");
6508
6512
  const config = loadConfig();
6509
6513
  const db = createClient(config.database);
6510
6514
  migrate(db);
@@ -102,6 +102,7 @@ import {
102
102
  contentTargetDismissalDtoSchema,
103
103
  contentTargetDismissalsResponseDtoSchema,
104
104
  contentTargetsResponseDtoSchema,
105
+ cosineSimilarity,
105
106
  createApiKeyRequestSchema,
106
107
  createdApiKeyDtoSchema,
107
108
  dedupeReportActions,
@@ -270,7 +271,7 @@ import {
270
271
  wordpressSchemaDeployResultDtoSchema,
271
272
  wordpressSchemaStatusResultDtoSchema,
272
273
  wordpressStatusDtoSchema
273
- } from "./chunk-ZT7GVLS3.js";
274
+ } from "./chunk-VICGMHY2.js";
274
275
 
275
276
  // src/intelligence-service.ts
276
277
  import { eq as eq38, desc as desc18, asc as asc6, and as and28, ne as ne5, or as or6, inArray as inArray14, gte as gte7, lte as lte4 } from "drizzle-orm";
@@ -34278,14 +34279,41 @@ async function classifyCompetitorDomains(deps, project, icpDescription, domains)
34278
34279
  return {};
34279
34280
  }
34280
34281
  }
34281
- async function pickCanonicalsWithStats(candidates, deps, dedupThreshold) {
34282
+ async function pickCanonicalsWithStats(candidates, deps, dedupThreshold, primaryMask) {
34282
34283
  const emptyStats = { perClusterMinSimilarity: [], bandPairFraction: null, pairsTotal: 0 };
34283
34284
  if (candidates.length === 0) return { canonicals: [], stats: emptyStats };
34284
34285
  if (candidates.length === 1) return { canonicals: candidates, stats: emptyStats };
34285
34286
  const vectors = await deps.embed(candidates);
34286
- const indexClusters = clusterByCosine(candidates.map((_, i) => i), vectors, dedupThreshold);
34287
- const canonicals = indexClusters.map((cluster) => pickClusterRepresentative(cluster.map((i) => candidates[i])));
34288
- return { canonicals, stats: computeDedupSimilarityStats(vectors, indexClusters) };
34287
+ const indices = candidates.map((_, i) => i);
34288
+ const hasBothRoles = primaryMask !== void 0 && primaryMask.length === candidates.length && primaryMask.some((p) => p) && primaryMask.some((p) => !p);
34289
+ if (!hasBothRoles) {
34290
+ const indexClusters = clusterByCosine(indices, vectors, dedupThreshold);
34291
+ const canonicals = indexClusters.map((cluster) => pickClusterRepresentative(cluster.map((i) => candidates[i])));
34292
+ return { canonicals, stats: computeDedupSimilarityStats(vectors, indexClusters) };
34293
+ }
34294
+ const primaryIdx = indices.filter((i) => primaryMask[i]);
34295
+ const primaryClusters = clusterByCosine(
34296
+ primaryIdx,
34297
+ primaryIdx.map((i) => vectors[i]),
34298
+ dedupThreshold
34299
+ );
34300
+ const repIndexOf = (cluster) => {
34301
+ const rep = pickClusterRepresentative(cluster.map((i) => candidates[i]));
34302
+ return cluster.find((i) => candidates[i] === rep);
34303
+ };
34304
+ const keptIdx = primaryClusters.map(repIndexOf);
34305
+ for (const s of indices.filter((i) => !primaryMask[i])) {
34306
+ const novel = keptIdx.every((k) => cosineSimilarity(vectors[s], vectors[k]) < dedupThreshold);
34307
+ if (novel) keptIdx.push(s);
34308
+ }
34309
+ return {
34310
+ canonicals: keptIdx.map((i) => candidates[i]),
34311
+ // Band fraction describes the candidate SPACE (not the clustering), so it is
34312
+ // computed over all vectors as before; per-cluster cohesion reports the
34313
+ // primary clusters.
34314
+ stats: computeDedupSimilarityStats(vectors, primaryClusters),
34315
+ primaryCanonicalCount: primaryClusters.length
34316
+ };
34289
34317
  }
34290
34318
  async function executeDiscovery(opts) {
34291
34319
  const dedupThreshold = opts.dedupThreshold ?? DISCOVERY_DEFAULT_DEDUP_THRESHOLD;
@@ -34315,10 +34343,22 @@ async function executeDiscovery(opts) {
34315
34343
  });
34316
34344
  const rawCandidates = dedupeStrings(unbrandedCandidates);
34317
34345
  const seedCountRaw = rawCandidates.length;
34346
+ const primaryProvider = opts.seedProviders?.[0];
34347
+ const multiProvider = (opts.seedProviders?.length ?? 0) >= 2 && seedResult.candidateProviders != null;
34348
+ let primaryMask;
34349
+ if (multiProvider && primaryProvider) {
34350
+ const providerOf = /* @__PURE__ */ new Map();
34351
+ seedResult.candidates.forEach((candidate, i) => {
34352
+ const key = candidate.trim().toLowerCase();
34353
+ if (!providerOf.has(key)) providerOf.set(key, seedResult.candidateProviders[i]);
34354
+ });
34355
+ primaryMask = rawCandidates.map((c) => providerOf.get(c.trim().toLowerCase()) === primaryProvider);
34356
+ }
34318
34357
  const { canonicals, stats: dedupStats } = await pickCanonicalsWithStats(
34319
34358
  rawCandidates,
34320
34359
  { embed: opts.deps.embed },
34321
- dedupThreshold
34360
+ dedupThreshold,
34361
+ primaryMask
34322
34362
  );
34323
34363
  const warning = seedCollapseWarning({
34324
34364
  seedCountRaw,
@@ -5763,6 +5763,7 @@ export {
5763
5763
  categorizeSource,
5764
5764
  categorizeSourceWithCompetitors,
5765
5765
  categoryLabel,
5766
+ cosineSimilarity,
5766
5767
  clusterByCosine,
5767
5768
  pickClusterRepresentative,
5768
5769
  computeDedupSimilarityStats,
package/dist/cli.js CHANGED
@@ -29,7 +29,7 @@ import {
29
29
  setTelemetrySource,
30
30
  showFirstRunNotice,
31
31
  trackEvent
32
- } from "./chunk-4TQOZJPF.js";
32
+ } from "./chunk-KS2M7B5E.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-Y26GYDS6.js";
49
+ } from "./chunk-6M2ALGJA.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-CVXBE3ST.js";
57
+ } from "./chunk-UOMNYP5T.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-ZT7GVLS3.js";
83
+ } from "./chunk-VICGMHY2.js";
84
84
 
85
85
  // src/cli.ts
86
86
  import { pathToFileURL } from "url";
@@ -2076,9 +2076,9 @@ function compareToBaseline(scorecards, baseline) {
2076
2076
  `${base.shape}: canonicalCount ${current.canonicalCount} vs baseline ${base.canonicalCount} (band: >= ${EVAL_BANDS.canonicalCountFactor}x)`
2077
2077
  );
2078
2078
  }
2079
- if (current.retention < base.retention - EVAL_BANDS.retentionDrop) {
2079
+ if (current.canonicalCount < base.canonicalCount && current.retention < base.retention - EVAL_BANDS.retentionDrop) {
2080
2080
  regressions.push(
2081
- `${base.shape}: retention ${current.retention.toFixed(2)} vs baseline ${base.retention.toFixed(2)} (band: -${EVAL_BANDS.retentionDrop})`
2081
+ `${base.shape}: retention ${current.retention.toFixed(2)} vs baseline ${base.retention.toFixed(2)} (band: -${EVAL_BANDS.retentionDrop}), with canonicals also down (${current.canonicalCount} < ${base.canonicalCount})`
2082
2082
  );
2083
2083
  }
2084
2084
  const brandCeiling = Math.min(base.brandShare + EVAL_BANDS.brandShareSlack, EVAL_BANDS.brandShareCeiling);
package/dist/index.js CHANGED
@@ -1,11 +1,11 @@
1
1
  import {
2
2
  createServer
3
- } from "./chunk-4TQOZJPF.js";
3
+ } from "./chunk-KS2M7B5E.js";
4
4
  import {
5
5
  loadConfig
6
- } from "./chunk-Y26GYDS6.js";
7
- import "./chunk-CVXBE3ST.js";
8
- import "./chunk-ZT7GVLS3.js";
6
+ } from "./chunk-6M2ALGJA.js";
7
+ import "./chunk-UOMNYP5T.js";
8
+ import "./chunk-VICGMHY2.js";
9
9
  export {
10
10
  createServer,
11
11
  loadConfig
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  IntelligenceService
3
- } from "./chunk-CVXBE3ST.js";
4
- import "./chunk-ZT7GVLS3.js";
3
+ } from "./chunk-UOMNYP5T.js";
4
+ import "./chunk-VICGMHY2.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-Y26GYDS6.js";
6
+ } from "./chunk-6M2ALGJA.js";
7
7
  import {
8
8
  isReadOnlyKey
9
- } from "./chunk-ZT7GVLS3.js";
9
+ } from "./chunk-VICGMHY2.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.111.0",
3
+ "version": "4.112.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",
@@ -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-bing": "0.0.0",
74
- "@ainyc/canonry-integration-openai-ads": "0.0.0",
72
+ "@ainyc/canonry-contracts": "0.0.0",
75
73
  "@ainyc/canonry-integration-cloud-run": "0.0.0",
74
+ "@ainyc/canonry-integration-bing": "0.0.0",
76
75
  "@ainyc/canonry-integration-google": "0.0.0",
77
- "@ainyc/canonry-integration-google-places": "0.0.0",
78
- "@ainyc/canonry-integration-google-business-profile": "0.0.0",
79
76
  "@ainyc/canonry-integration-commoncrawl": "0.0.0",
80
- "@ainyc/canonry-integration-traffic": "0.0.0",
81
- "@ainyc/canonry-intelligence": "0.0.0",
77
+ "@ainyc/canonry-integration-google-business-profile": "0.0.0",
78
+ "@ainyc/canonry-integration-google-places": "0.0.0",
79
+ "@ainyc/canonry-integration-openai-ads": "0.0.0",
82
80
  "@ainyc/canonry-integration-wordpress": "0.0.0",
81
+ "@ainyc/canonry-intelligence": "0.0.0",
83
82
  "@ainyc/canonry-provider-cdp": "0.0.0",
83
+ "@ainyc/canonry-provider-claude": "0.0.0",
84
84
  "@ainyc/canonry-provider-gemini": "0.0.0",
85
+ "@ainyc/canonry-integration-traffic": "0.0.0",
85
86
  "@ainyc/canonry-provider-local": "0.0.0",
86
- "@ainyc/canonry-provider-claude": "0.0.0",
87
- "@ainyc/canonry-provider-openai": "0.0.0",
88
- "@ainyc/canonry-provider-perplexity": "0.0.0"
87
+ "@ainyc/canonry-provider-perplexity": "0.0.0",
88
+ "@ainyc/canonry-provider-openai": "0.0.0"
89
89
  },
90
90
  "scripts": {
91
91
  "build": "tsx scripts/copy-agent-assets.ts && tsup && tsx build-web.ts",