@ainyc/canonry 4.41.1 → 4.43.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.
package/assets/index.html CHANGED
@@ -12,8 +12,8 @@
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-JiyuncvN.js"></script>
16
- <link rel="stylesheet" crossorigin href="./assets/index-Ca1Lty3H.css">
15
+ <script type="module" crossorigin src="./assets/index-kRilKhIW.js"></script>
16
+ <link rel="stylesheet" crossorigin href="./assets/index-jvmhx0du.css">
17
17
  </head>
18
18
  <body>
19
19
  <div id="root"></div>
@@ -32,12 +32,13 @@ import {
32
32
  buildMentionCoverage,
33
33
  buildMentionGapScore,
34
34
  buildMentionLandscape,
35
+ buildMentionShare,
35
36
  buildMovementSummary,
36
37
  buildOverviewCompetitors,
37
38
  buildProviderScores,
38
39
  buildProviderTrends,
39
40
  buildRunHistory,
40
- buildShareOfVoice,
41
+ buildSuggestedQueries,
41
42
  buildVisibilityScore,
42
43
  categorizeQueryByIntent,
43
44
  ccReleaseSyncs,
@@ -78,7 +79,7 @@ import {
78
79
  schedules,
79
80
  trafficSources,
80
81
  usageCounters
81
- } from "./chunk-3I6Y2PSQ.js";
82
+ } from "./chunk-MITJYCHG.js";
82
83
  import {
83
84
  AGENT_MEMORY_VALUE_MAX_BYTES,
84
85
  AGENT_PROVIDER_IDS,
@@ -6428,7 +6429,7 @@ function buildReportActionPlan(input) {
6428
6429
  action: "Review the recurring external source domains and add the true competitors before the next check.",
6429
6430
  why: [
6430
6431
  "The report can identify repeated external sources, but it cannot separate competitors from publishers until competitors are configured.",
6431
- "A clean competitor set makes future share-of-voice and content-gap reporting easier to explain to clients."
6432
+ "A clean competitor set makes future mention-share and content-gap reporting easier to explain to clients."
6432
6433
  ],
6433
6434
  evidence: topDomains.map((d) => `${d.domain} appeared in ${d.count} cited source${d.count === 1 ? "" : "s"}`),
6434
6435
  successMetric: "Next report separates tracked competitors from independent source domains in the competitor landscape.",
@@ -7239,17 +7240,23 @@ async function compositeRoutes(app) {
7239
7240
  const projectQueries = app.db.select({ id: queries.id, query: queries.query }).from(queries).where(eq15(queries.projectId, project.id)).all();
7240
7241
  const queryLookup = { byId: new Map(projectQueries.map((q) => [q.id, q.query])) };
7241
7242
  const configuredApiProviders = parseJsonColumn(project.providers, []).filter((p) => !p.startsWith("cdp:"));
7242
- const projectDomains = effectiveDomains({
7243
- canonicalDomain: project.canonicalDomain,
7244
- ownedDomains: parseJsonColumn(project.ownedDomains, [])
7245
- });
7243
+ const mentionShareCompetitors = competitorRows.map((c) => ({
7244
+ domain: c.domain,
7245
+ // Single brand token derived from the registrable domain (e.g.
7246
+ // "offers.roofle.com" → "roofle"). Future PR can layer operator-curated
7247
+ // aliases on top via a `competitor_aliases` column.
7248
+ brandTokens: [brandLabelFromDomain(c.domain)].filter((t) => t.length >= 3)
7249
+ }));
7246
7250
  const scores = {
7247
7251
  mention: buildMentionCoverage(latestSnapshots, { configuredApiProviders }),
7248
7252
  visibility: buildVisibilityScore(latestSnapshots, { configuredApiProviders }),
7249
- shareOfVoice: buildShareOfVoice(latestSnapshots, {
7250
- projectDomains,
7251
- competitorDomains: competitorRows.map((c) => c.domain)
7252
- }),
7253
+ mentionShare: buildMentionShare(
7254
+ latestSnapshots.map((s) => ({
7255
+ projectMentioned: s.answerMentioned === true,
7256
+ answerText: s.answerText
7257
+ })),
7258
+ { competitors: mentionShareCompetitors }
7259
+ ),
7253
7260
  gapQueries: buildGapQueryScore(latestSnapshots),
7254
7261
  mentionGaps: buildMentionGapScore(latestSnapshots),
7255
7262
  indexCoverage: buildIndexCoverageScore(app, project.id),
@@ -7281,6 +7288,11 @@ async function compositeRoutes(app) {
7281
7288
  const attentionItems = buildAttentionItems(insightRows, allRuns);
7282
7289
  const sparklineRuns = visibilityRuns.slice(0, DEFAULT_RUN_HISTORY_LIMIT).map((r) => ({ id: r.id, createdAt: r.createdAt, status: r.status }));
7283
7290
  const runHistory = buildRunHistory(sparklineRuns, snapshotsByRun);
7291
+ const suggestedQueries = buildSuggestedQueriesFromGsc(
7292
+ app,
7293
+ project.id,
7294
+ projectQueries.map((q) => q.query)
7295
+ );
7284
7296
  const result = {
7285
7297
  project: formatProject2(project),
7286
7298
  latestRun,
@@ -7295,6 +7307,7 @@ async function compositeRoutes(app) {
7295
7307
  providerScores,
7296
7308
  attentionItems,
7297
7309
  runHistory,
7310
+ suggestedQueries,
7298
7311
  dateRangeLabel: "All time",
7299
7312
  contextLabel: `${project.country} / ${project.language.toUpperCase()}`
7300
7313
  };
@@ -7412,6 +7425,7 @@ function loadSnapshotsByRunIds(app, runIds) {
7412
7425
  model: querySnapshots.model,
7413
7426
  citationState: querySnapshots.citationState,
7414
7427
  answerMentioned: querySnapshots.answerMentioned,
7428
+ answerText: querySnapshots.answerText,
7415
7429
  competitorOverlap: querySnapshots.competitorOverlap,
7416
7430
  citedDomains: querySnapshots.citedDomains
7417
7431
  }).from(querySnapshots).where(inArray8(querySnapshots.runId, [...runIds])).all());
@@ -7423,6 +7437,7 @@ function loadSnapshotsByRunIds(app, runIds) {
7423
7437
  model: row.model,
7424
7438
  citationState: row.citationState,
7425
7439
  answerMentioned: row.answerMentioned,
7440
+ answerText: row.answerText,
7426
7441
  competitorOverlap: parseJsonColumn(row.competitorOverlap, []),
7427
7442
  citedDomains: parseJsonColumn(row.citedDomains, [])
7428
7443
  });
@@ -7494,6 +7509,29 @@ function summarizeTransitionsFromSnapshots(latest, previous, since) {
7494
7509
  }
7495
7510
  return { since, gained, lost, emerging };
7496
7511
  }
7512
+ function buildSuggestedQueriesFromGsc(app, projectId, trackedQueries) {
7513
+ const cutoff = new Date(Date.now() - 28 * 24 * 60 * 60 * 1e3).toISOString().slice(0, 10);
7514
+ const rows = app.db.select({
7515
+ query: gscSearchData.query,
7516
+ impressions: sql6`COALESCE(SUM(${gscSearchData.impressions}), 0)`,
7517
+ clicks: sql6`COALESCE(SUM(${gscSearchData.clicks}), 0)`,
7518
+ // Weighted average: SUM(position * impressions) / SUM(impressions).
7519
+ // NULLIF guards the degenerate impressions=0 case (SQLite returns NULL,
7520
+ // which the JS coerces to 0 — caught by the impression floor anyway).
7521
+ avgPosition: sql6`COALESCE(SUM(${gscSearchData.position} * ${gscSearchData.impressions}) * 1.0 / NULLIF(SUM(${gscSearchData.impressions}), 0), 0)`
7522
+ }).from(gscSearchData).where(and7(
7523
+ eq15(gscSearchData.projectId, projectId),
7524
+ sql6`${gscSearchData.date} >= ${cutoff}`,
7525
+ sql6`${gscSearchData.impressions} > 0`
7526
+ )).groupBy(gscSearchData.query).orderBy(sql6`SUM(${gscSearchData.impressions}) DESC`).limit(100).all();
7527
+ const gscRows = rows.map((r) => ({
7528
+ query: r.query,
7529
+ impressions: Number(r.impressions),
7530
+ clicks: Number(r.clicks),
7531
+ avgPosition: Number(r.avgPosition)
7532
+ }));
7533
+ return buildSuggestedQueries(gscRows, { trackedQueries });
7534
+ }
7497
7535
  function buildIndexCoverageScore(app, projectId) {
7498
7536
  const tooltip = "Percentage of inspected URLs currently indexed. Google Search Console is preferred when available, otherwise Bing Webmaster Tools is used.";
7499
7537
  const empty = {
@@ -26271,7 +26309,7 @@ function readStoredGroundingSources(rawResponse) {
26271
26309
  return result;
26272
26310
  }
26273
26311
  async function backfillInsightsCommand(project, opts) {
26274
- const { IntelligenceService: IntelligenceService2 } = await import("./intelligence-service-FFCEIEOU.js");
26312
+ const { IntelligenceService: IntelligenceService2 } = await import("./intelligence-service-HWWNLBZM.js");
26275
26313
  const config = loadConfig();
26276
26314
  const db = createClient(config.database);
26277
26315
  migrate(db);
@@ -3,6 +3,7 @@ import {
3
3
  ContentActions,
4
4
  RunKinds,
5
5
  __export,
6
+ brandKeyFromText,
6
7
  brandLabelFromDomain,
7
8
  categorizeSourceWithCompetitors,
8
9
  categoryLabel,
@@ -3589,92 +3590,6 @@ function buildRunHistory(runs2, snapshotsByRunId, limit = DEFAULT_RUN_HISTORY_LI
3589
3590
  });
3590
3591
  }
3591
3592
 
3592
- // ../intelligence/src/share-of-voice.ts
3593
- function sovTone(score) {
3594
- if (score >= 30) return "positive";
3595
- if (score >= 10) return "caution";
3596
- return "negative";
3597
- }
3598
- function buildShareOfVoice(snapshots, options) {
3599
- const tooltip = "Your domain's share of every distinct cited-source slot across the latest run. Subdomain-aware (cited docs.you.com counts for you.com). Distinct from Citation Coverage \u2014 SoV measures how much of the answer real-estate you own, not just whether you appear.";
3600
- if (snapshots.length === 0) {
3601
- return {
3602
- label: "Share of Voice",
3603
- value: "No data",
3604
- delta: "Run a sweep first",
3605
- tone: "neutral",
3606
- description: "No SoV data yet. Trigger a run to start tracking.",
3607
- tooltip,
3608
- trend: []
3609
- };
3610
- }
3611
- const breakdown = computeShareOfVoiceBreakdown(snapshots, options);
3612
- if (breakdown.totalSlots === 0) {
3613
- return {
3614
- label: "Share of Voice",
3615
- value: "0",
3616
- delta: "No citations in this run",
3617
- tone: "neutral",
3618
- description: "The latest run produced no source-list citations across any provider, so SoV cannot be measured. (Mention Coverage may still be non-zero \u2014 answers can mention you without grounding to a URL.)",
3619
- tooltip,
3620
- trend: [],
3621
- progress: 0
3622
- };
3623
- }
3624
- const { projectSlots, competitorSlots, otherSlots, totalSlots } = breakdown;
3625
- const score = Math.round(projectSlots / totalSlots * 100);
3626
- const competitorShare = Math.round(competitorSlots / totalSlots * 100);
3627
- const otherShare = Math.max(0, 100 - score - competitorShare);
3628
- const hasCompetitorsConfigured = options.competitorDomains.length > 0;
3629
- const description = describeBreakdown({
3630
- projectSlots,
3631
- competitorSlots,
3632
- otherSlots,
3633
- totalSlots,
3634
- score,
3635
- competitorShare,
3636
- otherShare,
3637
- hasCompetitorsConfigured
3638
- });
3639
- return {
3640
- label: "Share of Voice",
3641
- value: `${score}`,
3642
- delta: `${projectSlots} of ${totalSlots} cited slots`,
3643
- tone: sovTone(score),
3644
- description,
3645
- tooltip,
3646
- trend: [],
3647
- progress: score
3648
- };
3649
- }
3650
- function computeShareOfVoiceBreakdown(snapshots, options) {
3651
- let totalSlots = 0;
3652
- let projectSlots = 0;
3653
- let competitorSlots = 0;
3654
- for (const snap of snapshots) {
3655
- for (const domain of snap.citedDomains) {
3656
- totalSlots++;
3657
- if (citedDomainBelongsToProject(domain, options.projectDomains)) {
3658
- projectSlots++;
3659
- } else if (citedDomainBelongsToProject(domain, options.competitorDomains)) {
3660
- competitorSlots++;
3661
- }
3662
- }
3663
- }
3664
- const otherSlots = totalSlots - projectSlots - competitorSlots;
3665
- return { projectSlots, competitorSlots, otherSlots, totalSlots };
3666
- }
3667
- function describeBreakdown(parts) {
3668
- const { projectSlots, competitorSlots, totalSlots, score, competitorShare, otherShare, hasCompetitorsConfigured } = parts;
3669
- if (!hasCompetitorsConfigured) {
3670
- return `${projectSlots} of ${totalSlots} cited slots were yours (${score}%). Add tracked competitors to break out the rest.`;
3671
- }
3672
- if (competitorSlots === 0) {
3673
- return `${projectSlots} of ${totalSlots} cited slots were yours (${score}%); no tracked competitors surfaced in the run. The remaining ${otherShare}% goes to unrelated sources.`;
3674
- }
3675
- return `You own ${score}% of cited slots; tracked competitors hold ${competitorShare}%; the remaining ${otherShare}% goes to non-competitive sources.`;
3676
- }
3677
-
3678
3593
  // ../intelligence/src/provider-trends.ts
3679
3594
  function buildProviderTrends(runs2, snapshotsByRunId, limit = 12) {
3680
3595
  const recent = [...runs2].sort((a, b) => b.createdAt.localeCompare(a.createdAt)).slice(0, limit).sort((a, b) => a.createdAt.localeCompare(b.createdAt));
@@ -3712,6 +3627,172 @@ function collectProviderKeys(perRun) {
3712
3627
  return keys;
3713
3628
  }
3714
3629
 
3630
+ // ../intelligence/src/mention-share.ts
3631
+ function buildMentionShare(snapshots, options) {
3632
+ const tooltip = 'When AI answers your tracked queries and names a brand, the % of brand-name-drops that are you vs your tracked competitors. Cleaner than Citation Coverage for "am I winning the conversation".';
3633
+ const emptyBreakdown = {
3634
+ projectMentionSnapshots: 0,
3635
+ competitorMentionSnapshots: 0,
3636
+ perCompetitor: [],
3637
+ snapshotsWithAnswerText: 0,
3638
+ snapshotsTotal: snapshots.length
3639
+ };
3640
+ if (snapshots.length === 0) {
3641
+ return {
3642
+ label: "Mention Share",
3643
+ value: "No data",
3644
+ delta: "Run a sweep first",
3645
+ tone: "neutral",
3646
+ description: "No mention share data yet. Trigger a run to start tracking.",
3647
+ tooltip,
3648
+ trend: [],
3649
+ breakdown: emptyBreakdown
3650
+ };
3651
+ }
3652
+ if (options.competitors.length === 0) {
3653
+ return {
3654
+ label: "Mention Share",
3655
+ value: "Add competitors",
3656
+ delta: "No competitors configured",
3657
+ tone: "neutral",
3658
+ description: "Mention Share is a head-to-head competitive metric \u2014 add tracked competitors to compare brand mention rates.",
3659
+ tooltip,
3660
+ trend: [],
3661
+ breakdown: emptyBreakdown
3662
+ };
3663
+ }
3664
+ let projectMentionSnapshots = 0;
3665
+ let snapshotsWithAnswerText = 0;
3666
+ const competitorCounts = /* @__PURE__ */ new Map();
3667
+ for (const c of options.competitors) competitorCounts.set(c.domain, 0);
3668
+ for (const snap of snapshots) {
3669
+ const text2 = snap.answerText ?? "";
3670
+ if (text2.length === 0) continue;
3671
+ snapshotsWithAnswerText++;
3672
+ if (snap.projectMentioned) projectMentionSnapshots++;
3673
+ const answerBrandKey = brandKeyFromText(text2);
3674
+ for (const competitor of options.competitors) {
3675
+ if (competitorMentioned(text2, answerBrandKey, competitor.brandTokens)) {
3676
+ competitorCounts.set(competitor.domain, (competitorCounts.get(competitor.domain) ?? 0) + 1);
3677
+ }
3678
+ }
3679
+ }
3680
+ const competitorMentionSnapshots = [...competitorCounts.values()].reduce((a, b) => a + b, 0);
3681
+ const denom = projectMentionSnapshots + competitorMentionSnapshots;
3682
+ const score = denom > 0 ? Math.round(projectMentionSnapshots / denom * 100) : 0;
3683
+ const perCompetitor = options.competitors.map((c) => ({
3684
+ domain: c.domain,
3685
+ mentionSnapshots: competitorCounts.get(c.domain) ?? 0,
3686
+ shareOfCompetitiveTotal: competitorMentionSnapshots > 0 ? Math.round((competitorCounts.get(c.domain) ?? 0) / competitorMentionSnapshots * 1e3) / 10 : 0
3687
+ })).filter((row) => row.mentionSnapshots > 0).sort((a, b) => b.mentionSnapshots - a.mentionSnapshots);
3688
+ const breakdown = {
3689
+ projectMentionSnapshots,
3690
+ competitorMentionSnapshots,
3691
+ perCompetitor,
3692
+ snapshotsWithAnswerText,
3693
+ snapshotsTotal: snapshots.length
3694
+ };
3695
+ const description = describe({
3696
+ score,
3697
+ projectMentionSnapshots,
3698
+ competitorMentionSnapshots,
3699
+ perCompetitor
3700
+ });
3701
+ return {
3702
+ label: "Mention Share",
3703
+ value: denom > 0 ? `${score}` : "0",
3704
+ delta: denom > 0 ? `${projectMentionSnapshots} of ${denom} brand mentions` : "No brand mentions in this run",
3705
+ tone: denom > 0 ? mentionShareTone(score) : "neutral",
3706
+ description,
3707
+ tooltip,
3708
+ trend: [],
3709
+ progress: denom > 0 ? score : 0,
3710
+ breakdown
3711
+ };
3712
+ }
3713
+ function mentionShareTone(score) {
3714
+ if (score >= 50) return "positive";
3715
+ if (score >= 25) return "caution";
3716
+ return "negative";
3717
+ }
3718
+ function competitorMentioned(text2, answerBrandKey, brandTokens) {
3719
+ for (const token of brandTokens) {
3720
+ if (token.length < 3) continue;
3721
+ const escaped = token.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
3722
+ if (new RegExp(`\\b${escaped}\\b`, "i").test(text2)) return true;
3723
+ const tokenBrandKey = brandKeyFromText(token);
3724
+ if (tokenBrandKey.length >= 3 && answerBrandKey.includes(tokenBrandKey)) return true;
3725
+ }
3726
+ return false;
3727
+ }
3728
+ function describe(parts) {
3729
+ const { score, projectMentionSnapshots, competitorMentionSnapshots, perCompetitor } = parts;
3730
+ if (projectMentionSnapshots === 0 && competitorMentionSnapshots === 0) {
3731
+ return "No brand mentions detected for you or your tracked competitors in this run.";
3732
+ }
3733
+ if (competitorMentionSnapshots === 0) {
3734
+ return `${projectMentionSnapshots} brand mentions of you, zero competitor mentions \u2014 you own the conversation.`;
3735
+ }
3736
+ const top = perCompetitor[0];
3737
+ if (!top) {
3738
+ return `${score}% of brand mentions are you (${projectMentionSnapshots} of ${projectMentionSnapshots + competitorMentionSnapshots}).`;
3739
+ }
3740
+ return `${score}% of brand mentions are you. Top competitor: ${top.domain} (${top.mentionSnapshots} mentions).`;
3741
+ }
3742
+
3743
+ // ../intelligence/src/suggested-queries.ts
3744
+ var DEFAULT_MIN_IMPRESSIONS = 10;
3745
+ var DEFAULT_LIMIT = 10;
3746
+ function buildSuggestedQueries(gscRows, options) {
3747
+ const minImpressions = options.minImpressions ?? DEFAULT_MIN_IMPRESSIONS;
3748
+ const limit = options.limit ?? DEFAULT_LIMIT;
3749
+ const trackedSet = new Set(options.trackedQueries.map(normalizeQuery));
3750
+ let skippedAlreadyTracked = 0;
3751
+ const candidates = [];
3752
+ for (const row of gscRows) {
3753
+ if (row.impressions < minImpressions) continue;
3754
+ const normalized = normalizeQuery(row.query);
3755
+ if (normalized.length === 0) continue;
3756
+ if (trackedSet.has(normalized)) {
3757
+ skippedAlreadyTracked++;
3758
+ continue;
3759
+ }
3760
+ candidates.push({
3761
+ query: row.query,
3762
+ impressions: row.impressions,
3763
+ clicks: row.clicks,
3764
+ avgPosition: row.avgPosition,
3765
+ reason: buildReason(row)
3766
+ });
3767
+ }
3768
+ candidates.sort((a, b) => b.impressions - a.impressions);
3769
+ const rows = candidates.slice(0, limit);
3770
+ return {
3771
+ rows,
3772
+ totalCandidates: candidates.length,
3773
+ skippedAlreadyTracked
3774
+ };
3775
+ }
3776
+ function normalizeQuery(value) {
3777
+ return value.trim().toLowerCase();
3778
+ }
3779
+ function buildReason(row) {
3780
+ const impressionsLabel = formatImpressions2(row.impressions);
3781
+ if (row.avgPosition <= 10) {
3782
+ return `${impressionsLabel} impressions \xB7 ranks #${Math.round(row.avgPosition)} on Google`;
3783
+ }
3784
+ if (row.avgPosition <= 20) {
3785
+ return `${impressionsLabel} impressions \xB7 ranks #${Math.round(row.avgPosition)} \u2014 close to top 10`;
3786
+ }
3787
+ return `${impressionsLabel} impressions \xB7 ranks #${Math.round(row.avgPosition)}`;
3788
+ }
3789
+ function formatImpressions2(value) {
3790
+ if (value >= 1e6) return `${(value / 1e6).toFixed(1)}M`;
3791
+ if (value >= 1e4) return `${Math.round(value / 1e3)}K`;
3792
+ if (value >= 1e3) return `${(value / 1e3).toFixed(1)}K`;
3793
+ return value.toString();
3794
+ }
3795
+
3715
3796
  // src/intelligence-service.ts
3716
3797
  import crypto from "crypto";
3717
3798
 
@@ -4238,9 +4319,10 @@ export {
4238
4319
  buildProviderScores,
4239
4320
  DEFAULT_RUN_HISTORY_LIMIT,
4240
4321
  buildRunHistory,
4241
- buildShareOfVoice,
4242
4322
  buildProviderTrends,
4243
4323
  providerKey,
4324
+ buildMentionShare,
4325
+ buildSuggestedQueries,
4244
4326
  createLogger,
4245
4327
  IntelligenceService
4246
4328
  };
package/dist/cli.js CHANGED
@@ -21,7 +21,7 @@ import {
21
21
  setTelemetrySource,
22
22
  showFirstRunNotice,
23
23
  trackEvent
24
- } from "./chunk-PQ2IKBT5.js";
24
+ } from "./chunk-IXP4WGLQ.js";
25
25
  import {
26
26
  CliError,
27
27
  EXIT_SYSTEM_ERROR,
@@ -44,7 +44,7 @@ import {
44
44
  migrate,
45
45
  projects,
46
46
  queries
47
- } from "./chunk-3I6Y2PSQ.js";
47
+ } from "./chunk-MITJYCHG.js";
48
48
  import {
49
49
  CcReleaseSyncStatuses,
50
50
  CheckScopes,
package/dist/index.js CHANGED
@@ -1,10 +1,10 @@
1
1
  import {
2
2
  createServer
3
- } from "./chunk-PQ2IKBT5.js";
3
+ } from "./chunk-IXP4WGLQ.js";
4
4
  import {
5
5
  loadConfig
6
6
  } from "./chunk-JZ2VJW4U.js";
7
- import "./chunk-3I6Y2PSQ.js";
7
+ import "./chunk-MITJYCHG.js";
8
8
  import "./chunk-Q7XFJO2V.js";
9
9
  export {
10
10
  createServer,
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  IntelligenceService
3
- } from "./chunk-3I6Y2PSQ.js";
3
+ } from "./chunk-MITJYCHG.js";
4
4
  import "./chunk-Q7XFJO2V.js";
5
5
  export {
6
6
  IntelligenceService
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ainyc/canonry",
3
- "version": "4.41.1",
3
+ "version": "4.43.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",
@@ -61,22 +61,22 @@
61
61
  "tsup": "^8.5.1",
62
62
  "tsx": "^4.19.0",
63
63
  "@ainyc/canonry-api-routes": "0.0.0",
64
+ "@ainyc/canonry-contracts": "0.0.0",
65
+ "@ainyc/canonry-intelligence": "0.0.0",
64
66
  "@ainyc/canonry-config": "0.0.0",
65
67
  "@ainyc/canonry-db": "0.0.0",
66
- "@ainyc/canonry-intelligence": "0.0.0",
67
- "@ainyc/canonry-integration-bing": "0.0.0",
68
68
  "@ainyc/canonry-integration-cloud-run": "0.0.0",
69
- "@ainyc/canonry-contracts": "0.0.0",
70
- "@ainyc/canonry-integration-commoncrawl": "0.0.0",
69
+ "@ainyc/canonry-integration-bing": "0.0.0",
71
70
  "@ainyc/canonry-integration-google": "0.0.0",
72
71
  "@ainyc/canonry-integration-traffic": "0.0.0",
73
72
  "@ainyc/canonry-integration-wordpress": "0.0.0",
74
- "@ainyc/canonry-provider-gemini": "0.0.0",
75
73
  "@ainyc/canonry-provider-cdp": "0.0.0",
76
74
  "@ainyc/canonry-provider-claude": "0.0.0",
77
- "@ainyc/canonry-provider-openai": "0.0.0",
75
+ "@ainyc/canonry-provider-gemini": "0.0.0",
76
+ "@ainyc/canonry-integration-commoncrawl": "0.0.0",
77
+ "@ainyc/canonry-provider-perplexity": "0.0.0",
78
78
  "@ainyc/canonry-provider-local": "0.0.0",
79
- "@ainyc/canonry-provider-perplexity": "0.0.0"
79
+ "@ainyc/canonry-provider-openai": "0.0.0"
80
80
  },
81
81
  "scripts": {
82
82
  "build": "tsx scripts/copy-agent-assets.ts && tsup && tsx build-web.ts",