@ainyc/canonry 4.107.0 → 4.108.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 (22) hide show
  1. package/assets/assets/{BacklinksPage-Cuvg9TTn.js → BacklinksPage-Dr6MK4h1.js} +1 -1
  2. package/assets/assets/{ChartPrimitives-CoNjLN3a.js → ChartPrimitives-DGO0EGqM.js} +1 -1
  3. package/assets/assets/{ProjectPage-DhEoUnmx.js → ProjectPage-fHczny77.js} +1 -1
  4. package/assets/assets/{RunRow-Du9r-Mik.js → RunRow-Br6uOqD1.js} +1 -1
  5. package/assets/assets/{RunsPage-LIvuym9f.js → RunsPage-MMEhx2vt.js} +1 -1
  6. package/assets/assets/{SettingsPage-BrFy3IsH.js → SettingsPage-BjZZODA1.js} +1 -1
  7. package/assets/assets/{TrafficPage-C16J18tV.js → TrafficPage-BtMtH6FT.js} +1 -1
  8. package/assets/assets/{TrafficSourceDetailPage-BtOwcgWX.js → TrafficSourceDetailPage-DFFGJsVC.js} +1 -1
  9. package/assets/assets/{arrow-left-DL0hZP8l.js → arrow-left-DDnYTDM6.js} +1 -1
  10. package/assets/assets/{extract-error-message-CgHHv6eH.js → extract-error-message-B0KSa98X.js} +1 -1
  11. package/assets/assets/{index-54KuHvPl.js → index-imKX6Edq.js} +46 -46
  12. package/assets/assets/{trash-2-CpYdnCg2.js → trash-2-BODtOdNo.js} +1 -1
  13. package/assets/index.html +1 -1
  14. package/dist/{chunk-QLWRJEII.js → chunk-45YSA7GH.js} +40 -12
  15. package/dist/{chunk-KRP555VO.js → chunk-EKGKGKID.js} +1 -1
  16. package/dist/{chunk-NDXV6EYD.js → chunk-EMG4LIUJ.js} +8 -5
  17. package/dist/{chunk-MV3ZJOI7.js → chunk-IQX7XXJN.js} +10 -0
  18. package/dist/cli.js +4 -4
  19. package/dist/index.js +4 -4
  20. package/dist/{intelligence-service-2DQLZUPW.js → intelligence-service-YDPWS7OC.js} +2 -2
  21. package/dist/mcp.js +2 -2
  22. package/package.json +7 -7
@@ -1 +1 @@
1
- import{c}from"./index-54KuHvPl.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-imKX6Edq.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,7 +12,7 @@
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-54KuHvPl.js"></script>
15
+ <script type="module" crossorigin src="./assets/index-imKX6Edq.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">
@@ -184,6 +184,7 @@ import {
184
184
  notFound,
185
185
  notImplemented,
186
186
  notificationDtoSchema,
187
+ orderLocationsDefaultFirst,
187
188
  parseInclusiveEndMs,
188
189
  parseReportPeriodDays,
189
190
  parseRunError,
@@ -268,10 +269,10 @@ import {
268
269
  wordpressSchemaDeployResultDtoSchema,
269
270
  wordpressSchemaStatusResultDtoSchema,
270
271
  wordpressStatusDtoSchema
271
- } from "./chunk-MV3ZJOI7.js";
272
+ } from "./chunk-IQX7XXJN.js";
272
273
 
273
274
  // src/intelligence-service.ts
274
- import { eq as eq38, desc as desc18, asc as asc6, and as and28, ne as ne5, or as or5, inArray as inArray14, gte as gte7, lte as lte4 } from "drizzle-orm";
275
+ 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";
275
276
 
276
277
  // ../db/src/client.ts
277
278
  import { mkdirSync } from "fs";
@@ -1148,6 +1149,9 @@ var discoverySessions = sqliteTable("discovery_sessions", {
1148
1149
  // Buyer definition the session was seeded with; part of session identity
1149
1150
  // for in-flight consolidation (same ICP + different buyer never reuses).
1150
1151
  buyerDescription: text("buyer_description"),
1152
+ // Resolved service areas the session was seeded/probed with; part of session
1153
+ // identity for in-flight consolidation. Null on legacy sessions.
1154
+ locations: text("locations", { mode: "json" }).$type(),
1151
1155
  dedupThreshold: real("dedup_threshold"),
1152
1156
  probeCount: integer("probe_count"),
1153
1157
  citedCount: integer("cited_count"),
@@ -3417,6 +3421,17 @@ var MIGRATION_VERSIONS = [
3417
3421
  // reuse another buyer's session) and auditability for seed provenance.
3418
3422
  `ALTER TABLE discovery_sessions ADD COLUMN buyer_description TEXT`
3419
3423
  ]
3424
+ },
3425
+ {
3426
+ version: 91,
3427
+ name: "discovery-session-locations",
3428
+ statements: [
3429
+ // Resolved service areas the session was seeded/probed with. Part of the
3430
+ // in-flight consolidation identity (a different location subset never
3431
+ // reuses another geo's session) and seed/probe provenance. Nullable —
3432
+ // legacy sessions stay null.
3433
+ `ALTER TABLE discovery_sessions ADD COLUMN locations TEXT`
3434
+ ]
3420
3435
  }
3421
3436
  ];
3422
3437
  function rebuildBacklinkTableWithSource(tx, table) {
@@ -3609,7 +3624,7 @@ function getAppliedVersion(db) {
3609
3624
  function recordMigration(db, version, name) {
3610
3625
  db.run(sql`INSERT OR IGNORE INTO _migrations (version, name) VALUES (${version}, ${name})`);
3611
3626
  }
3612
- function migrate(db) {
3627
+ function migrate(db, versions = MIGRATION_VERSIONS) {
3613
3628
  db.transaction((tx) => {
3614
3629
  normalizeLegacyQuerySchema(tx);
3615
3630
  });
@@ -3618,7 +3633,7 @@ function migrate(db) {
3618
3633
  db.run(sql.raw(statement));
3619
3634
  }
3620
3635
  const appliedVersion = getAppliedVersion(db);
3621
- for (const mv of MIGRATION_VERSIONS) {
3636
+ for (const mv of versions) {
3622
3637
  if (mv.version <= appliedVersion) continue;
3623
3638
  db.transaction((tx) => {
3624
3639
  for (const statement of mv.statements) {
@@ -33757,7 +33772,7 @@ async function doctorRoutes(app, opts) {
33757
33772
 
33758
33773
  // ../api-routes/src/discovery/routes.ts
33759
33774
  import crypto27 from "crypto";
33760
- import { and as and26, desc as desc16, eq as eq35, gte as gte6, inArray as inArray12, isNull } from "drizzle-orm";
33775
+ import { and as and26, desc as desc16, eq as eq35, gte as gte6, inArray as inArray12, isNull, or as or5 } from "drizzle-orm";
33761
33776
  var MAX_INFLIGHT_DISCOVERY_AGE_MS = 2 * 60 * 60 * 1e3;
33762
33777
  async function discoveryRoutes(app, opts) {
33763
33778
  app.post("/projects/:name/discover/run", async (request, reply) => {
@@ -33777,9 +33792,9 @@ async function discoveryRoutes(app, opts) {
33777
33792
  "icpDescription is required. Pass it in the request body or store it on the project (spec.icpDescription)."
33778
33793
  );
33779
33794
  }
33780
- const locations = resolveLocations(
33781
- project.locations,
33782
- parsed.data.locations
33795
+ const locations = orderLocationsDefaultFirst(
33796
+ resolveLocations(project.locations, parsed.data.locations),
33797
+ project.defaultLocation
33783
33798
  );
33784
33799
  if (!opts.onDiscoveryRunRequested) {
33785
33800
  throw validationError("Discovery is not available on this deployment.", {
@@ -33796,6 +33811,16 @@ async function discoveryRoutes(app, opts) {
33796
33811
  // semantics, so a request with a different (or no) buyer must start
33797
33812
  // its own session, never adopt another buyer's probes.
33798
33813
  parsed.data.buyerDescription == null ? isNull(discoverySessions.buyerDescription) : eq35(discoverySessions.buyerDescription, parsed.data.buyerDescription),
33814
+ // Locations are identity too: a different service-area subset seeds
33815
+ // and probes a different geo, so it must never reuse another geo's
33816
+ // session. resolveLocations is deterministic (project-config order),
33817
+ // so equal subsets always serialize identically. Legacy in-flight
33818
+ // rows (pre-91) carry NULL: on a NO-location project that geo is
33819
+ // unambiguous (always []), so NULL matches; on a project WITH
33820
+ // locations a NULL row's subset is unknowable, so it conservatively
33821
+ // never reuses — a one-time, bounded (2h window) non-reuse after
33822
+ // upgrade, never a wrong reuse.
33823
+ locations.length === 0 ? or5(isNull(discoverySessions.locations), eq35(discoverySessions.locations, locations)) : eq35(discoverySessions.locations, locations),
33799
33824
  inArray12(discoverySessions.status, [
33800
33825
  DiscoverySessionStatuses.queued,
33801
33826
  DiscoverySessionStatuses.seeding,
@@ -33815,6 +33840,7 @@ async function discoveryRoutes(app, opts) {
33815
33840
  status: DiscoverySessionStatuses.queued,
33816
33841
  icpDescription,
33817
33842
  buyerDescription: parsed.data.buyerDescription ?? null,
33843
+ locations,
33818
33844
  dedupThreshold: parsed.data.dedupThreshold,
33819
33845
  competitorMap: [],
33820
33846
  createdAt: now
@@ -34106,6 +34132,7 @@ function serializeSession(row) {
34106
34132
  seedFromGroundingCount: row.seedFromGroundingCount ?? null,
34107
34133
  seedBrandFilteredCount: row.seedBrandFilteredCount ?? null,
34108
34134
  buyerDescription: row.buyerDescription ?? null,
34135
+ locations: row.locations ?? null,
34109
34136
  dedupThreshold: row.dedupThreshold ?? null,
34110
34137
  probeCount: row.probeCount ?? null,
34111
34138
  citedCount: row.citedCount ?? null,
@@ -34246,10 +34273,11 @@ async function executeDiscovery(opts) {
34246
34273
  seedBrandFilteredCount: droppedBranded.length,
34247
34274
  warning
34248
34275
  }).where(eq36(discoverySessions.id, opts.sessionId)).run();
34276
+ const probeLocation = opts.locations?.[0];
34249
34277
  const probeResults = await mapWithConcurrency(
34250
34278
  probedCanonicals,
34251
34279
  probeConcurrency,
34252
- (query) => opts.deps.probe({ project: opts.project, query })
34280
+ (query) => opts.deps.probe({ project: opts.project, query, location: probeLocation })
34253
34281
  );
34254
34282
  const probeRows = [];
34255
34283
  const buckets = { cited: 0, aspirational: 0, "wasted-surface": 0 };
@@ -35068,7 +35096,7 @@ var IntelligenceService = class {
35068
35096
  const recentRuns = this.db.select().from(runs).where(
35069
35097
  and28(
35070
35098
  eq38(runs.projectId, projectId),
35071
- or5(eq38(runs.status, "completed"), eq38(runs.status, "partial")),
35099
+ or6(eq38(runs.status, "completed"), eq38(runs.status, "partial")),
35072
35100
  // Defensive: RunCoordinator already skips probes before this is
35073
35101
  // called, but if a future call site invokes analyzeAndPersist
35074
35102
  // directly for a probe, probes still must not pollute the
@@ -35371,7 +35399,7 @@ var IntelligenceService = class {
35371
35399
  const allRuns = this.db.select().from(runs).where(
35372
35400
  and28(
35373
35401
  eq38(runs.projectId, project.id),
35374
- or5(eq38(runs.status, "completed"), eq38(runs.status, "partial")),
35402
+ or6(eq38(runs.status, "completed"), eq38(runs.status, "partial")),
35375
35403
  // Backfill must not replay probe runs as if they were real sweeps.
35376
35404
  ne5(runs.trigger, RunTriggers.probe)
35377
35405
  )
@@ -35549,7 +35577,7 @@ var IntelligenceService = class {
35549
35577
  and28(
35550
35578
  eq38(runs.projectId, projectId),
35551
35579
  eq38(runs.kind, RunKinds["answer-visibility"]),
35552
- or5(eq38(runs.status, "completed"), eq38(runs.status, "partial")),
35580
+ or6(eq38(runs.status, "completed"), eq38(runs.status, "partial")),
35553
35581
  // Defensive — see top of file.
35554
35582
  ne5(runs.trigger, RunTriggers.probe)
35555
35583
  )
@@ -25,7 +25,7 @@ import {
25
25
  trafficConnectVercelRequestSchema,
26
26
  trafficConnectWordpressRequestSchema,
27
27
  trafficEventKindSchema
28
- } from "./chunk-MV3ZJOI7.js";
28
+ } from "./chunk-IQX7XXJN.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-KRP555VO.js";
13
+ } from "./chunk-EKGKGKID.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-QLWRJEII.js";
118
+ } from "./chunk-45YSA7GH.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-MV3ZJOI7.js";
181
+ } from "./chunk-IQX7XXJN.js";
182
182
 
183
183
  // src/telemetry.ts
184
184
  import crypto from "crypto";
@@ -5649,7 +5649,10 @@ function buildDefaultDeps(registry) {
5649
5649
  {
5650
5650
  query: input.query,
5651
5651
  canonicalDomains: input.project.canonicalDomains,
5652
- competitorDomains: input.project.competitorDomains
5652
+ competitorDomains: input.project.competitorDomains,
5653
+ // Same geo mechanism as sweeps: the provider renders the location
5654
+ // into the prompt so the probe measures from the buyer's area.
5655
+ ...input.location ? { location: input.location } : {}
5653
5656
  },
5654
5657
  cfg
5655
5658
  );
@@ -6482,7 +6485,7 @@ function readStoredGroundingSources(rawResponse) {
6482
6485
  return result;
6483
6486
  }
6484
6487
  async function backfillInsightsCommand(project, opts) {
6485
- const { IntelligenceService: IntelligenceService2 } = await import("./intelligence-service-2DQLZUPW.js");
6488
+ const { IntelligenceService: IntelligenceService2 } = await import("./intelligence-service-YDPWS7OC.js");
6486
6489
  const config = loadConfig();
6487
6490
  const db = createClient(config.database);
6488
6491
  migrate(db);
@@ -169,6 +169,12 @@ function hasLocationLabel(locations, label) {
169
169
  if (!label) return true;
170
170
  return locations.some((location) => location.label === label);
171
171
  }
172
+ function orderLocationsDefaultFirst(locations, defaultLabel) {
173
+ if (!defaultLabel) return [...locations];
174
+ const index = locations.findIndex((l) => l.label === defaultLabel);
175
+ if (index <= 0) return [...locations];
176
+ return [locations[index], ...locations.slice(0, index), ...locations.slice(index + 1)];
177
+ }
172
178
  function resolveLocations(projectLocations, requestedLabels) {
173
179
  const normalizedRequest = (requestedLabels ?? []).map((label) => label.trim()).filter((label) => label.length > 0);
174
180
  if (normalizedRequest.length === 0) return [...projectLocations];
@@ -2196,6 +2202,9 @@ var discoverySessionDtoSchema = z17.object({
2196
2202
  /** Buyer definition the session was seeded with (part of session identity
2197
2203
  * for in-flight consolidation). Null on legacy / no-buyer sessions. */
2198
2204
  buyerDescription: z17.string().nullable().optional(),
2205
+ /** Resolved service areas the session was seeded/probed with (part of
2206
+ * session identity for in-flight consolidation). Null on legacy sessions. */
2207
+ locations: z17.array(locationContextSchema).nullable().optional(),
2199
2208
  dedupThreshold: z17.number().nullable().optional(),
2200
2209
  probeCount: z17.number().int().nullable().optional(),
2201
2210
  citedCount: z17.number().int().nullable().default(null),
@@ -5591,6 +5600,7 @@ export {
5591
5600
  runtimeStateMissing,
5592
5601
  findDuplicateLocationLabels,
5593
5602
  hasLocationLabel,
5603
+ orderLocationsDefaultFirst,
5594
5604
  resolveLocations,
5595
5605
  projectUpsertRequestSchema,
5596
5606
  projectDtoSchema,
package/dist/cli.js CHANGED
@@ -29,7 +29,7 @@ import {
29
29
  setTelemetrySource,
30
30
  showFirstRunNotice,
31
31
  trackEvent
32
- } from "./chunk-NDXV6EYD.js";
32
+ } from "./chunk-EMG4LIUJ.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-KRP555VO.js";
49
+ } from "./chunk-EKGKGKID.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-QLWRJEII.js";
57
+ } from "./chunk-45YSA7GH.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-MV3ZJOI7.js";
83
+ } from "./chunk-IQX7XXJN.js";
84
84
 
85
85
  // src/cli.ts
86
86
  import { pathToFileURL } from "url";
package/dist/index.js CHANGED
@@ -1,11 +1,11 @@
1
1
  import {
2
2
  createServer
3
- } from "./chunk-NDXV6EYD.js";
3
+ } from "./chunk-EMG4LIUJ.js";
4
4
  import {
5
5
  loadConfig
6
- } from "./chunk-KRP555VO.js";
7
- import "./chunk-QLWRJEII.js";
8
- import "./chunk-MV3ZJOI7.js";
6
+ } from "./chunk-EKGKGKID.js";
7
+ import "./chunk-45YSA7GH.js";
8
+ import "./chunk-IQX7XXJN.js";
9
9
  export {
10
10
  createServer,
11
11
  loadConfig
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  IntelligenceService
3
- } from "./chunk-QLWRJEII.js";
4
- import "./chunk-MV3ZJOI7.js";
3
+ } from "./chunk-45YSA7GH.js";
4
+ import "./chunk-IQX7XXJN.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-KRP555VO.js";
6
+ } from "./chunk-EKGKGKID.js";
7
7
  import {
8
8
  isReadOnlyKey
9
- } from "./chunk-MV3ZJOI7.js";
9
+ } from "./chunk-IQX7XXJN.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.107.0",
3
+ "version": "4.108.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",
@@ -74,18 +74,18 @@
74
74
  "@ainyc/canonry-integration-openai-ads": "0.0.0",
75
75
  "@ainyc/canonry-integration-cloud-run": "0.0.0",
76
76
  "@ainyc/canonry-integration-commoncrawl": "0.0.0",
77
- "@ainyc/canonry-integration-google-places": "0.0.0",
78
77
  "@ainyc/canonry-integration-google": "0.0.0",
79
- "@ainyc/canonry-integration-wordpress": "0.0.0",
80
- "@ainyc/canonry-integration-google-business-profile": "0.0.0",
78
+ "@ainyc/canonry-integration-google-places": "0.0.0",
81
79
  "@ainyc/canonry-integration-traffic": "0.0.0",
80
+ "@ainyc/canonry-integration-google-business-profile": "0.0.0",
81
+ "@ainyc/canonry-integration-wordpress": "0.0.0",
82
82
  "@ainyc/canonry-intelligence": "0.0.0",
83
- "@ainyc/canonry-provider-claude": "0.0.0",
84
83
  "@ainyc/canonry-provider-cdp": "0.0.0",
84
+ "@ainyc/canonry-provider-claude": "0.0.0",
85
85
  "@ainyc/canonry-provider-gemini": "0.0.0",
86
+ "@ainyc/canonry-provider-perplexity": "0.0.0",
86
87
  "@ainyc/canonry-provider-local": "0.0.0",
87
- "@ainyc/canonry-provider-openai": "0.0.0",
88
- "@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",