@ainyc/canonry 2.14.2 → 2.15.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.
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-D1v6Q-fS.js"></script>
16
- <link rel="stylesheet" crossorigin href="./assets/index-U2SLimrz.css">
15
+ <script type="module" crossorigin src="./assets/index-D0BgyJJT.js"></script>
16
+ <link rel="stylesheet" crossorigin href="./assets/index-DMx3Oy9W.css">
17
17
  </head>
18
18
  <body>
19
19
  <div id="root"></div>
@@ -60,7 +60,7 @@ import {
60
60
  visibilityStateFromAnswerMentioned,
61
61
  windowCutoff,
62
62
  wordpressEnvSchema
63
- } from "./chunk-7VWSR5F6.js";
63
+ } from "./chunk-OX24LLIH.js";
64
64
  import {
65
65
  IntelligenceService,
66
66
  agentMemory,
@@ -8848,6 +8848,10 @@ async function ga4Routes(app, opts) {
8848
8848
  GROUP BY date, source, medium
8849
8849
  )`
8850
8850
  ).get();
8851
+ const aiBySession = app.db.select({
8852
+ sessions: sql5`COALESCE(SUM(${gaAiReferrals.sessions}), 0)`,
8853
+ users: sql5`COALESCE(SUM(${gaAiReferrals.users}), 0)`
8854
+ }).from(gaAiReferrals).where(and8(...aiConditions, eq19(gaAiReferrals.sourceDimension, "session"))).get();
8851
8855
  const socialReferrals = app.db.select({
8852
8856
  source: gaSocialReferrals.source,
8853
8857
  medium: gaSocialReferrals.medium,
@@ -8883,6 +8887,8 @@ async function ga4Routes(app, opts) {
8883
8887
  })),
8884
8888
  aiSessionsDeduped: aiDeduped?.sessions ?? 0,
8885
8889
  aiUsersDeduped: aiDeduped?.users ?? 0,
8890
+ aiSessionsBySession: aiBySession?.sessions ?? 0,
8891
+ aiUsersBySession: aiBySession?.users ?? 0,
8886
8892
  socialReferrals: socialReferrals.map((r) => ({
8887
8893
  source: r.source,
8888
8894
  medium: r.medium,
@@ -8894,6 +8900,7 @@ async function ga4Routes(app, opts) {
8894
8900
  socialUsers: socialTotals?.users ?? 0,
8895
8901
  organicSharePct: total > 0 ? Math.round((summaryRow?.totalOrganicSessions ?? 0) / total * 100) : 0,
8896
8902
  aiSharePct: total > 0 ? Math.round((aiDeduped?.sessions ?? 0) / total * 100) : 0,
8903
+ aiSharePctBySession: total > 0 ? Math.round((aiBySession?.sessions ?? 0) / total * 100) : 0,
8897
8904
  directSharePct: total > 0 ? Math.round(totalDirectSessions / total * 100) : 0,
8898
8905
  socialSharePct: total > 0 ? Math.round((socialTotals?.sessions ?? 0) / total * 100) : 0,
8899
8906
  lastSyncedAt: latestSync?.syncedAt ?? null,
@@ -9013,12 +9020,13 @@ async function ga4Routes(app, opts) {
9013
9020
  const pct = (cur, prev) => prev === 0 ? null : Math.round((cur - prev) / prev * 100);
9014
9021
  const sumTotal = (from, to) => app.db.select({ sessions: sql5`COALESCE(SUM(${gaTrafficSnapshots.sessions}), 0)` }).from(gaTrafficSnapshots).where(and8(eq19(gaTrafficSnapshots.projectId, project.id), sql5`${gaTrafficSnapshots.date} >= ${from}`, sql5`${gaTrafficSnapshots.date} < ${to}`)).get();
9015
9022
  const sumOrganic = (from, to) => app.db.select({ sessions: sql5`COALESCE(SUM(${gaTrafficSnapshots.organicSessions}), 0)` }).from(gaTrafficSnapshots).where(and8(eq19(gaTrafficSnapshots.projectId, project.id), sql5`${gaTrafficSnapshots.date} >= ${from}`, sql5`${gaTrafficSnapshots.date} < ${to}`)).get();
9016
- const sumAi = (from, to) => app.db.select({ sessions: sql5`COALESCE(SUM(max_sessions), 0)` }).from(sql5`(
9017
- SELECT date, source, medium, MAX(sessions) AS max_sessions
9018
- FROM ga_ai_referrals
9019
- WHERE project_id = ${project.id} AND date >= ${from} AND date < ${to}
9020
- GROUP BY date, source, medium
9021
- )`).get();
9023
+ const sumDirect = (from, to) => app.db.select({ sessions: sql5`COALESCE(SUM(${gaTrafficSnapshots.directSessions}), 0)` }).from(gaTrafficSnapshots).where(and8(eq19(gaTrafficSnapshots.projectId, project.id), sql5`${gaTrafficSnapshots.date} >= ${from}`, sql5`${gaTrafficSnapshots.date} < ${to}`)).get();
9024
+ const sumAi = (from, to) => app.db.select({ sessions: sql5`COALESCE(SUM(${gaAiReferrals.sessions}), 0)` }).from(gaAiReferrals).where(and8(
9025
+ eq19(gaAiReferrals.projectId, project.id),
9026
+ sql5`${gaAiReferrals.date} >= ${from}`,
9027
+ sql5`${gaAiReferrals.date} < ${to}`,
9028
+ eq19(gaAiReferrals.sourceDimension, "session")
9029
+ )).get();
9022
9030
  const sumSocial = (from, to) => app.db.select({ sessions: sql5`COALESCE(SUM(${gaSocialReferrals.sessions}), 0)` }).from(gaSocialReferrals).where(and8(eq19(gaSocialReferrals.projectId, project.id), sql5`${gaSocialReferrals.date} >= ${from}`, sql5`${gaSocialReferrals.date} < ${to}`)).get();
9023
9031
  const todayStr = fmt(today);
9024
9032
  const buildTrend = (sum) => {
@@ -9028,18 +9036,18 @@ async function ga4Routes(app, opts) {
9028
9036
  const p30 = sum(daysAgo2(60), daysAgo2(30))?.sessions ?? 0;
9029
9037
  return { sessions7d: c7, sessionsPrev7d: p7, trend7dPct: pct(c7, p7), sessions30d: c30, sessionsPrev30d: p30, trend30dPct: pct(c30, p30) };
9030
9038
  };
9031
- const aiSourceCurrent = app.db.select({ source: sql5`source`, sessions: sql5`COALESCE(SUM(max_sessions), 0)` }).from(sql5`(
9032
- SELECT date, source, medium, MAX(sessions) AS max_sessions
9033
- FROM ga_ai_referrals
9034
- WHERE project_id = ${project.id} AND date >= ${daysAgo2(7)} AND date < ${todayStr}
9035
- GROUP BY date, source, medium
9036
- )`).groupBy(sql5`source`).all();
9037
- const aiSourcePrev = app.db.select({ source: sql5`source`, sessions: sql5`COALESCE(SUM(max_sessions), 0)` }).from(sql5`(
9038
- SELECT date, source, medium, MAX(sessions) AS max_sessions
9039
- FROM ga_ai_referrals
9040
- WHERE project_id = ${project.id} AND date >= ${daysAgo2(14)} AND date < ${daysAgo2(7)}
9041
- GROUP BY date, source, medium
9042
- )`).groupBy(sql5`source`).all();
9039
+ const aiSourceCurrent = app.db.select({ source: gaAiReferrals.source, sessions: sql5`COALESCE(SUM(${gaAiReferrals.sessions}), 0)` }).from(gaAiReferrals).where(and8(
9040
+ eq19(gaAiReferrals.projectId, project.id),
9041
+ sql5`${gaAiReferrals.date} >= ${daysAgo2(7)}`,
9042
+ sql5`${gaAiReferrals.date} < ${todayStr}`,
9043
+ eq19(gaAiReferrals.sourceDimension, "session")
9044
+ )).groupBy(gaAiReferrals.source).all();
9045
+ const aiSourcePrev = app.db.select({ source: gaAiReferrals.source, sessions: sql5`COALESCE(SUM(${gaAiReferrals.sessions}), 0)` }).from(gaAiReferrals).where(and8(
9046
+ eq19(gaAiReferrals.projectId, project.id),
9047
+ sql5`${gaAiReferrals.date} >= ${daysAgo2(14)}`,
9048
+ sql5`${gaAiReferrals.date} < ${daysAgo2(7)}`,
9049
+ eq19(gaAiReferrals.sourceDimension, "session")
9050
+ )).groupBy(gaAiReferrals.source).all();
9043
9051
  const findBiggestMover = (current, prev) => {
9044
9052
  const prevMap = new Map(prev.map((r) => [r.source, r.sessions]));
9045
9053
  let mover = null;
@@ -9061,6 +9069,7 @@ async function ga4Routes(app, opts) {
9061
9069
  organic: buildTrend(sumOrganic),
9062
9070
  ai: buildTrend(sumAi),
9063
9071
  social: buildTrend(sumSocial),
9072
+ direct: buildTrend(sumDirect),
9064
9073
  aiBiggestMover: findBiggestMover(aiSourceCurrent, aiSourcePrev),
9065
9074
  socialBiggestMover: findBiggestMover(socialSourceCurrent, socialSourcePrev)
9066
9075
  };
@@ -1310,10 +1310,14 @@ var ga4TrafficSummaryDtoSchema = z12.object({
1310
1310
  users: z12.number()
1311
1311
  })),
1312
1312
  aiReferrals: z12.array(ga4AiReferralDtoSchema),
1313
- /** Deduped AI session total: MAX(sessions) per date+source+medium across attribution dimensions, then summed. */
1313
+ /** Deduped AI session total: MAX(sessions) per date+source+medium across attribution dimensions, then summed. Cross-cutting: can overlap with Direct/Organic/Social via firstUserSource. */
1314
1314
  aiSessionsDeduped: z12.number(),
1315
1315
  /** Deduped AI user total: MAX(users) per date+source+medium across attribution dimensions, then summed. */
1316
1316
  aiUsersDeduped: z12.number(),
1317
+ /** AI sessions whose CURRENT sessionSource matched an AI engine. Disjoint from Direct/Organic/Social — safe for the channel breakdown. */
1318
+ aiSessionsBySession: z12.number(),
1319
+ /** AI users whose CURRENT sessionSource matched an AI engine. Disjoint from Direct/Organic/Social — safe for the channel breakdown. */
1320
+ aiUsersBySession: z12.number(),
1317
1321
  socialReferrals: z12.array(ga4SocialReferralDtoSchema),
1318
1322
  /** Total social sessions (session-scoped, no cross-dimension dedup needed). */
1319
1323
  socialSessions: z12.number(),
@@ -1321,8 +1325,10 @@ var ga4TrafficSummaryDtoSchema = z12.object({
1321
1325
  socialUsers: z12.number(),
1322
1326
  /** Organic sessions as a percentage of total sessions (0–100, rounded). */
1323
1327
  organicSharePct: z12.number(),
1324
- /** Deduped AI sessions as a percentage of total sessions (0–100, rounded). */
1328
+ /** Deduped AI sessions as a percentage of total sessions (0–100, rounded). Cross-cutting: can overlap with Direct/Organic/Social. */
1325
1329
  aiSharePct: z12.number(),
1330
+ /** Session-source-only AI sessions as a percentage of total sessions (0–100, rounded). Disjoint from Direct/Organic/Social. */
1331
+ aiSharePctBySession: z12.number(),
1326
1332
  /** Direct-channel sessions as a percentage of total sessions (0–100, rounded). */
1327
1333
  directSharePct: z12.number(),
1328
1334
  /** Social sessions as a percentage of total sessions (0–100, rounded). */
@@ -1847,9 +1853,19 @@ function dropTrailingSlash(path2) {
1847
1853
  }
1848
1854
  function normalizeUrlPath(input) {
1849
1855
  if (input == null) return null;
1850
- const trimmed = input.trim();
1856
+ let trimmed = input.trim();
1851
1857
  if (trimmed === "") return null;
1858
+ trimmed = trimmed.replace(/&nbsp;/g, " ").replace(/\s+/g, " ").trim();
1859
+ if (trimmed === "" || trimmed === "/") return "/";
1852
1860
  if (trimmed === "(not set)") return null;
1861
+ trimmed = trimmed.replace(/([a-zA-Z0-9])([).]+)$/, "$1");
1862
+ if (trimmed.startsWith("/)") || trimmed.startsWith("/ ")) {
1863
+ trimmed = "/";
1864
+ }
1865
+ if (trimmed.includes(" ")) {
1866
+ trimmed = trimmed.split(" ")[0];
1867
+ }
1868
+ if (trimmed === "" || trimmed === "/") return "/";
1853
1869
  let pathPart;
1854
1870
  let queryPart;
1855
1871
  if (/^https?:\/\//i.test(trimmed)) {
package/dist/cli.js CHANGED
@@ -17,7 +17,7 @@ import {
17
17
  setGoogleAuthConfig,
18
18
  showFirstRunNotice,
19
19
  trackEvent
20
- } from "./chunk-CILBPOHB.js";
20
+ } from "./chunk-KANIG6ES.js";
21
21
  import {
22
22
  CcReleaseSyncStatuses,
23
23
  CheckScopes,
@@ -45,7 +45,7 @@ import {
45
45
  saveConfig,
46
46
  saveConfigPatch,
47
47
  usageError
48
- } from "./chunk-7VWSR5F6.js";
48
+ } from "./chunk-OX24LLIH.js";
49
49
  import {
50
50
  apiKeys,
51
51
  competitors,
@@ -162,7 +162,7 @@ Usage: ${spec.usage}`, {
162
162
  }
163
163
 
164
164
  // src/commands/backfill.ts
165
- import { and, eq, inArray, isNull } from "drizzle-orm";
165
+ import { and, eq, inArray } from "drizzle-orm";
166
166
  var SNAPSHOT_BATCH_SIZE = 500;
167
167
  async function backfillAnswerVisibilityCommand(opts) {
168
168
  const config = loadConfig();
@@ -304,14 +304,15 @@ async function backfillAnswerVisibilityCommand(opts) {
304
304
  console.log(` Errors: ${providerErrors}`);
305
305
  }
306
306
  function backfillNormalizedPaths(db, opts) {
307
- const baseConditions = [isNull(gaTrafficSnapshots.landingPageNormalized)];
307
+ const baseConditions = [];
308
308
  if (opts?.projectId) {
309
309
  baseConditions.push(eq(gaTrafficSnapshots.projectId, opts.projectId));
310
310
  }
311
311
  const rows = db.select({
312
312
  id: gaTrafficSnapshots.id,
313
- landingPage: gaTrafficSnapshots.landingPage
314
- }).from(gaTrafficSnapshots).where(and(...baseConditions)).all();
313
+ landingPage: gaTrafficSnapshots.landingPage,
314
+ landingPageNormalized: gaTrafficSnapshots.landingPageNormalized
315
+ }).from(gaTrafficSnapshots).where(baseConditions.length > 0 ? and(...baseConditions) : void 0).all();
315
316
  let updated = 0;
316
317
  let unchanged = 0;
317
318
  if (rows.length > 0) {
@@ -322,6 +323,10 @@ function backfillNormalizedPaths(db, opts) {
322
323
  unchanged++;
323
324
  continue;
324
325
  }
326
+ if (row.landingPageNormalized === next) {
327
+ unchanged++;
328
+ continue;
329
+ }
325
330
  tx.update(gaTrafficSnapshots).set({ landingPageNormalized: next }).where(eq(gaTrafficSnapshots.id, row.id)).run();
326
331
  updated++;
327
332
  }
@@ -2105,11 +2110,16 @@ async function gaAttribution(project, opts) {
2105
2110
  organicSessions: traffic.totalOrganicSessions,
2106
2111
  aiSessions: traffic.aiSessionsDeduped,
2107
2112
  aiUsers: traffic.aiUsersDeduped,
2113
+ aiSessionsBySession: traffic.aiSessionsBySession,
2114
+ aiUsersBySession: traffic.aiUsersBySession,
2108
2115
  socialSessions: traffic.socialSessions,
2109
2116
  socialUsers: traffic.socialUsers,
2117
+ directSessions: traffic.totalDirectSessions,
2110
2118
  aiSharePct: traffic.aiSharePct,
2119
+ aiSharePctBySession: traffic.aiSharePctBySession,
2111
2120
  socialSharePct: traffic.socialSharePct,
2112
2121
  organicSharePct: traffic.organicSharePct,
2122
+ directSharePct: traffic.directSharePct,
2113
2123
  aiReferrals: traffic.aiReferrals,
2114
2124
  socialReferrals: traffic.socialReferrals,
2115
2125
  trend
@@ -2127,9 +2137,10 @@ async function gaAttribution(project, opts) {
2127
2137
  console.log();
2128
2138
  console.log(" CHANNEL BREAKDOWN 7d trend 30d trend");
2129
2139
  console.log(` Organic Search: ${String(traffic.totalOrganicSessions).padEnd(6)} (${String(traffic.organicSharePct).padStart(2)}%) ${fmtTrend(trend.organic.trend7dPct).padEnd(12)} ${fmtTrend(trend.organic.trend30dPct)}`);
2130
- console.log(` AI Referrals: ${String(traffic.aiSessionsDeduped).padEnd(6)} (${String(traffic.aiSharePct).padStart(2)}%) ${fmtTrend(trend.ai.trend7dPct).padEnd(12)} ${fmtTrend(trend.ai.trend30dPct)}`);
2131
2140
  console.log(` Social: ${String(traffic.socialSessions).padEnd(6)} (${String(traffic.socialSharePct).padStart(2)}%) ${fmtTrend(trend.social.trend7dPct).padEnd(12)} ${fmtTrend(trend.social.trend30dPct)}`);
2132
- const otherSessions2 = traffic.totalSessions - traffic.totalOrganicSessions - traffic.aiSessionsDeduped - traffic.socialSessions;
2141
+ console.log(` Direct: ${String(traffic.totalDirectSessions).padEnd(6)} (${String(traffic.directSharePct).padStart(2)}%) ${fmtTrend(trend.direct.trend7dPct).padEnd(12)} ${fmtTrend(trend.direct.trend30dPct)}`);
2142
+ console.log(` AI Referrals: ${String(traffic.aiSessionsBySession).padEnd(6)} (${String(traffic.aiSharePctBySession).padStart(2)}%) ${fmtTrend(trend.ai.trend7dPct).padEnd(12)} ${fmtTrend(trend.ai.trend30dPct)} (lower bound \u2014 sessionSource only; referrer-stripped traffic falls under Direct)`);
2143
+ const otherSessions2 = traffic.totalSessions - traffic.totalOrganicSessions - traffic.aiSessionsBySession - traffic.socialSessions - traffic.totalDirectSessions;
2133
2144
  if (otherSessions2 > 0) {
2134
2145
  const otherPct = traffic.totalSessions > 0 ? Math.round(otherSessions2 / traffic.totalSessions * 100) : 0;
2135
2146
  console.log(` Other: ${String(otherSessions2).padEnd(6)} (${String(otherPct).padStart(2)}%)`);
@@ -2161,11 +2172,16 @@ async function gaAttribution(project, opts) {
2161
2172
  organicSessions: traffic.totalOrganicSessions,
2162
2173
  aiSessions: traffic.aiSessionsDeduped,
2163
2174
  aiUsers: traffic.aiUsersDeduped,
2175
+ aiSessionsBySession: traffic.aiSessionsBySession,
2176
+ aiUsersBySession: traffic.aiUsersBySession,
2164
2177
  socialSessions: traffic.socialSessions,
2165
2178
  socialUsers: traffic.socialUsers,
2179
+ directSessions: traffic.totalDirectSessions,
2166
2180
  aiSharePct: traffic.aiSharePct,
2181
+ aiSharePctBySession: traffic.aiSharePctBySession,
2167
2182
  socialSharePct: traffic.socialSharePct,
2168
2183
  organicSharePct: traffic.organicSharePct,
2184
+ directSharePct: traffic.directSharePct,
2169
2185
  aiReferrals: traffic.aiReferrals,
2170
2186
  socialReferrals: traffic.socialReferrals,
2171
2187
  periodStart: traffic.periodStart,
@@ -2184,9 +2200,10 @@ async function gaAttribution(project, opts) {
2184
2200
  console.log();
2185
2201
  console.log(" CHANNEL BREAKDOWN");
2186
2202
  console.log(` Organic Search: ${traffic.totalOrganicSessions} sessions (${traffic.organicSharePct}%)`);
2187
- console.log(` AI Referrals: ${traffic.aiSessionsDeduped} sessions (${traffic.aiSharePct}%)`);
2188
2203
  console.log(` Social: ${traffic.socialSessions} sessions (${traffic.socialSharePct}%)`);
2189
- const otherSessions = traffic.totalSessions - traffic.totalOrganicSessions - traffic.aiSessionsDeduped - traffic.socialSessions;
2204
+ console.log(` Direct: ${traffic.totalDirectSessions} sessions (${traffic.directSharePct}%)`);
2205
+ console.log(` AI Referrals: ${traffic.aiSessionsBySession} sessions (${traffic.aiSharePctBySession}%) (lower bound \u2014 sessionSource only; referrer-stripped traffic falls under Direct)`);
2206
+ const otherSessions = traffic.totalSessions - traffic.totalOrganicSessions - traffic.aiSessionsBySession - traffic.socialSessions - traffic.totalDirectSessions;
2190
2207
  if (otherSessions > 0) {
2191
2208
  const otherPct = traffic.totalSessions > 0 ? Math.round(otherSessions / traffic.totalSessions * 100) : 0;
2192
2209
  console.log(` Other: ${otherSessions} sessions (${otherPct}%)`);
package/dist/index.js CHANGED
@@ -1,9 +1,9 @@
1
1
  import {
2
2
  createServer
3
- } from "./chunk-CILBPOHB.js";
3
+ } from "./chunk-KANIG6ES.js";
4
4
  import {
5
5
  loadConfig
6
- } from "./chunk-7VWSR5F6.js";
6
+ } from "./chunk-OX24LLIH.js";
7
7
  import "./chunk-NEDRCOOL.js";
8
8
  import "./chunk-MLKGABMK.js";
9
9
  export {
package/dist/mcp.js CHANGED
@@ -10,7 +10,7 @@ import {
10
10
  projectUpsertRequestSchema,
11
11
  runTriggerRequestSchema,
12
12
  scheduleUpsertRequestSchema
13
- } from "./chunk-7VWSR5F6.js";
13
+ } from "./chunk-OX24LLIH.js";
14
14
  import "./chunk-MLKGABMK.js";
15
15
 
16
16
  // src/mcp/cli.ts
@@ -580,7 +580,7 @@ var canonryMcpTools = [
580
580
  defineTool({
581
581
  name: "canonry_ga_attribution_trend",
582
582
  title: "Get GA attribution trend",
583
- description: "Get per-channel attribution trends for organic, AI, social, and total sessions.",
583
+ description: "Get per-channel attribution trends for organic, AI, social, direct, and total sessions.",
584
584
  access: "read",
585
585
  tier: "ga",
586
586
  inputSchema: projectInputSchema,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ainyc/canonry",
3
- "version": "2.14.2",
3
+ "version": "2.15.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",
@@ -60,20 +60,20 @@
60
60
  "tsup": "^8.5.1",
61
61
  "tsx": "^4.19.0",
62
62
  "@ainyc/canonry-config": "0.0.0",
63
- "@ainyc/canonry-contracts": "0.0.0",
64
63
  "@ainyc/canonry-db": "0.0.0",
64
+ "@ainyc/canonry-integration-bing": "0.0.0",
65
+ "@ainyc/canonry-contracts": "0.0.0",
65
66
  "@ainyc/canonry-api-routes": "0.0.0",
66
- "@ainyc/canonry-intelligence": "0.0.0",
67
67
  "@ainyc/canonry-integration-commoncrawl": "0.0.0",
68
+ "@ainyc/canonry-intelligence": "0.0.0",
69
+ "@ainyc/canonry-integration-wordpress": "0.0.0",
68
70
  "@ainyc/canonry-integration-google": "0.0.0",
69
- "@ainyc/canonry-integration-bing": "0.0.0",
70
71
  "@ainyc/canonry-provider-cdp": "0.0.0",
71
- "@ainyc/canonry-integration-wordpress": "0.0.0",
72
- "@ainyc/canonry-provider-local": "0.0.0",
73
- "@ainyc/canonry-provider-perplexity": "0.0.0",
72
+ "@ainyc/canonry-provider-claude": "0.0.0",
74
73
  "@ainyc/canonry-provider-gemini": "0.0.0",
74
+ "@ainyc/canonry-provider-local": "0.0.0",
75
75
  "@ainyc/canonry-provider-openai": "0.0.0",
76
- "@ainyc/canonry-provider-claude": "0.0.0"
76
+ "@ainyc/canonry-provider-perplexity": "0.0.0"
77
77
  },
78
78
  "scripts": {
79
79
  "build": "tsx scripts/copy-agent-assets.ts && tsup && tsx build-web.ts",