@ainyc/canonry 4.109.0 → 4.110.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-D48kAAiT.js → BacklinksPage-Duk8YbV2.js} +1 -1
  2. package/assets/assets/{ChartPrimitives-CLSeu1W4.js → ChartPrimitives-aLxtVH28.js} +1 -1
  3. package/assets/assets/{ProjectPage-D20d2kjG.js → ProjectPage-Bqd0JvpC.js} +1 -1
  4. package/assets/assets/{RunRow-DQy-Gy9t.js → RunRow-DH8UMAwj.js} +1 -1
  5. package/assets/assets/{RunsPage-DRRG4uZS.js → RunsPage-OPteH1b_.js} +1 -1
  6. package/assets/assets/{SettingsPage-Pf0B9gMT.js → SettingsPage-7cspMOFv.js} +1 -1
  7. package/assets/assets/{TrafficPage-Cd2OL96L.js → TrafficPage-D4pcnfc8.js} +1 -1
  8. package/assets/assets/{TrafficSourceDetailPage-CiyttCo2.js → TrafficSourceDetailPage-D-KbCCEK.js} +1 -1
  9. package/assets/assets/{arrow-left-DaIR4jsx.js → arrow-left-M8KVuve8.js} +1 -1
  10. package/assets/assets/{extract-error-message-HqopXrW4.js → extract-error-message-D2aTaSV5.js} +1 -1
  11. package/assets/assets/{index-CthlUeHu.js → index-ChPgQUZ5.js} +42 -42
  12. package/assets/assets/{trash-2-DUel-9g8.js → trash-2-BNVgf5NY.js} +1 -1
  13. package/assets/index.html +1 -1
  14. package/dist/{chunk-YEOLQT5S.js → chunk-6PHBWPPN.js} +39 -19
  15. package/dist/{chunk-3HKBUYIY.js → chunk-JGRVQJHX.js} +29 -1
  16. package/dist/{chunk-QZQLZL3C.js → chunk-X4LLTNQZ.js} +2 -1
  17. package/dist/{chunk-WXAHSQOX.js → chunk-YQ4KOC5Z.js} +15 -0
  18. package/dist/cli.js +13 -8
  19. package/dist/index.js +4 -4
  20. package/dist/{intelligence-service-NXZXNM7T.js → intelligence-service-BGLF7DQW.js} +2 -2
  21. package/dist/mcp.js +2 -2
  22. package/package.json +8 -8
@@ -1 +1 @@
1
- import{c}from"./index-CthlUeHu.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-ChPgQUZ5.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-CthlUeHu.js"></script>
15
+ <script type="module" crossorigin src="./assets/index-ChPgQUZ5.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">
@@ -10,7 +10,7 @@ import {
10
10
  loadConfig,
11
11
  loadConfigRaw,
12
12
  saveConfigPatch
13
- } from "./chunk-QZQLZL3C.js";
13
+ } from "./chunk-X4LLTNQZ.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-3HKBUYIY.js";
118
+ } from "./chunk-JGRVQJHX.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-WXAHSQOX.js";
181
+ } from "./chunk-YQ4KOC5Z.js";
182
182
 
183
183
  // src/telemetry.ts
184
184
  import crypto from "crypto";
@@ -5573,6 +5573,7 @@ async function executeDiscoveryRun(opts) {
5573
5573
  project,
5574
5574
  icpDescription: opts.icpDescription,
5575
5575
  buyerDescription: opts.buyerDescription,
5576
+ seedProviders: opts.seedProviders,
5576
5577
  dedupThreshold: opts.dedupThreshold,
5577
5578
  maxProbes: opts.maxProbes,
5578
5579
  probeConcurrency: opts.probeConcurrency,
@@ -5614,27 +5615,45 @@ function buildDefaultDeps(registry) {
5614
5615
  throw new Error("Gemini provider is missing both apiKey and vertexProject \u2014 cannot run discovery.");
5615
5616
  }
5616
5617
  const adapter = gemini.adapter;
5618
+ function seedProviderFor(name) {
5619
+ if (name === "gemini") return { adapter, config: cfg };
5620
+ const entry = registry.get(name);
5621
+ if (!entry) {
5622
+ throw new Error(`Seed provider ${name} is not configured. Add its API key before requesting multi-provider seeding.`);
5623
+ }
5624
+ return { adapter: entry.adapter, config: entry.config };
5625
+ }
5617
5626
  return {
5618
5627
  async seed(input) {
5619
5628
  const prompt = buildSeedPrompt(input);
5620
- const raw = await adapter.executeTrackedQuery(
5621
- {
5622
- query: prompt,
5623
- canonicalDomains: input.project.canonicalDomains,
5624
- competitorDomains: input.project.competitorDomains
5625
- },
5626
- cfg
5629
+ const providerNames = input.seedProviders && input.seedProviders.length > 0 ? [...input.seedProviders] : ["gemini"];
5630
+ const perProvider = await Promise.all(providerNames.map(async (name) => {
5631
+ const seedProvider = seedProviderFor(name);
5632
+ const raw = await seedProvider.adapter.executeTrackedQuery(
5633
+ {
5634
+ query: prompt,
5635
+ canonicalDomains: input.project.canonicalDomains,
5636
+ competitorDomains: input.project.competitorDomains
5637
+ },
5638
+ seedProvider.config
5639
+ );
5640
+ const normalized = seedProvider.adapter.normalizeResult(raw);
5641
+ const fromAnswer = parseQueryLines(normalized.answerText, DEFAULT_SEED_COUNT * 2);
5642
+ const fromGrounding = normalized.searchQueries ?? [];
5643
+ return { name, fromAnswer, fromGrounding };
5644
+ }));
5645
+ const candidates = perProvider.flatMap((r) => [...r.fromAnswer, ...r.fromGrounding]);
5646
+ const providerCounts = Object.fromEntries(
5647
+ perProvider.map((r) => [r.name, r.fromAnswer.length + r.fromGrounding.length])
5627
5648
  );
5628
- const normalized = adapter.normalizeResult(raw);
5629
- const fromAnswer = parseQueryLines(normalized.answerText, DEFAULT_SEED_COUNT * 2);
5630
- const fromGrounding = normalized.searchQueries ?? [];
5631
5649
  return {
5632
- candidates: [...fromAnswer, ...fromGrounding],
5633
- provider: "gemini",
5634
- // Session diagnostics: the raw-candidate split by source, persisted on
5650
+ candidates,
5651
+ provider: providerNames.join("+"),
5652
+ // Session diagnostics: the raw-candidate splits, persisted on
5635
5653
  // discovery_sessions so seed-quality calibration is measurable.
5636
- fromAnswerCount: fromAnswer.length,
5637
- fromGroundingCount: fromGrounding.length
5654
+ fromAnswerCount: perProvider.reduce((n, r) => n + r.fromAnswer.length, 0),
5655
+ fromGroundingCount: perProvider.reduce((n, r) => n + r.fromGrounding.length, 0),
5656
+ providerCounts
5638
5657
  };
5639
5658
  },
5640
5659
  async embed(queries2) {
@@ -6485,7 +6504,7 @@ function readStoredGroundingSources(rawResponse) {
6485
6504
  return result;
6486
6505
  }
6487
6506
  async function backfillInsightsCommand(project, opts) {
6488
- const { IntelligenceService: IntelligenceService2 } = await import("./intelligence-service-NXZXNM7T.js");
6507
+ const { IntelligenceService: IntelligenceService2 } = await import("./intelligence-service-BGLF7DQW.js");
6489
6508
  const config = loadConfig();
6490
6509
  const db = createClient(config.database);
6491
6510
  migrate(db);
@@ -11951,6 +11970,7 @@ async function createServer(opts) {
11951
11970
  projectId: input.projectId,
11952
11971
  icpDescription: input.icpDescription,
11953
11972
  buyerDescription: input.buyerDescription,
11973
+ seedProviders: input.seedProviders,
11954
11974
  dedupThreshold: input.dedupThreshold,
11955
11975
  maxProbes: input.maxProbes,
11956
11976
  probeConcurrency: input.probeConcurrency,
@@ -270,7 +270,7 @@ import {
270
270
  wordpressSchemaDeployResultDtoSchema,
271
271
  wordpressSchemaStatusResultDtoSchema,
272
272
  wordpressStatusDtoSchema
273
- } from "./chunk-WXAHSQOX.js";
273
+ } from "./chunk-YQ4KOC5Z.js";
274
274
 
275
275
  // src/intelligence-service.ts
276
276
  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";
@@ -1160,6 +1160,10 @@ var discoverySessions = sqliteTable("discovery_sessions", {
1160
1160
  dedupClusterMinSims: text("dedup_cluster_min_sims", { mode: "json" }).$type(),
1161
1161
  dedupBandPairFraction: real("dedup_band_pair_fraction"),
1162
1162
  dedupPairsTotal: integer("dedup_pairs_total"),
1163
+ // Seed provider set (canonical order; null = legacy / Gemini-only) — part of
1164
+ // session identity for consolidation — and per-provider candidate counts.
1165
+ seedProviders: text("seed_providers", { mode: "json" }).$type(),
1166
+ seedProviderCounts: text("seed_provider_counts", { mode: "json" }).$type(),
1163
1167
  dedupThreshold: real("dedup_threshold"),
1164
1168
  probeCount: integer("probe_count"),
1165
1169
  citedCount: integer("cited_count"),
@@ -3452,6 +3456,16 @@ var MIGRATION_VERSIONS = [
3452
3456
  `ALTER TABLE discovery_sessions ADD COLUMN dedup_band_pair_fraction REAL`,
3453
3457
  `ALTER TABLE discovery_sessions ADD COLUMN dedup_pairs_total INTEGER`
3454
3458
  ]
3459
+ },
3460
+ {
3461
+ version: 93,
3462
+ name: "discovery-session-seed-providers",
3463
+ statements: [
3464
+ // Seed provider set (consolidation identity) + per-provider candidate
3465
+ // counts. Additive + nullable — legacy rows stay null (downgrade-safe).
3466
+ `ALTER TABLE discovery_sessions ADD COLUMN seed_providers TEXT`,
3467
+ `ALTER TABLE discovery_sessions ADD COLUMN seed_provider_counts TEXT`
3468
+ ]
3455
3469
  }
3456
3470
  ];
3457
3471
  function rebuildBacklinkTableWithSource(tx, table) {
@@ -18119,6 +18133,7 @@ var routeCatalog = [
18119
18133
  properties: {
18120
18134
  icpDescription: { type: "string", description: "Free-text ICP. Required if the project does not have spec.icpDescription stored." },
18121
18135
  buyerDescription: { type: "string", description: "Who evaluates or buys the offering, separate from the ICP. When present, every generated seed query is anchored on this buyer and the seed prompt enforces buyer-fit." },
18136
+ seedProviders: { type: "array", items: { type: "string", enum: ["gemini", "openai"] }, minItems: 1, description: "Which providers generate seed candidates. Omit for the Gemini-only default. Canonicalized (deduped + sorted); part of the session consolidation identity." },
18122
18137
  dedupThreshold: { type: "number", description: "Cosine similarity threshold for clustering. Defaults to 0.95." },
18123
18138
  maxProbes: { type: "integer", description: "Max canonical queries to probe in this session. Default 100, hard cap 500." },
18124
18139
  probeConcurrency: {
@@ -33812,6 +33827,8 @@ async function discoveryRoutes(app, opts) {
33812
33827
  "icpDescription is required. Pass it in the request body or store it on the project (spec.icpDescription)."
33813
33828
  );
33814
33829
  }
33830
+ const requestedSeedProviders = parsed.data.seedProviders ?? null;
33831
+ const seedProviders = requestedSeedProviders && !(requestedSeedProviders.length === 1 && requestedSeedProviders[0] === "gemini") ? requestedSeedProviders : null;
33815
33832
  const locations = orderLocationsDefaultFirst(
33816
33833
  resolveLocations(project.locations, parsed.data.locations),
33817
33834
  project.defaultLocation
@@ -33841,6 +33858,10 @@ async function discoveryRoutes(app, opts) {
33841
33858
  // never reuses — a one-time, bounded (2h window) non-reuse after
33842
33859
  // upgrade, never a wrong reuse.
33843
33860
  locations.length === 0 ? or5(isNull(discoverySessions.locations), eq35(discoverySessions.locations, locations)) : eq35(discoverySessions.locations, locations),
33861
+ // Seed provider set is identity: a different phrasing distribution
33862
+ // must never reuse another set's session. Null (= Gemini-only
33863
+ // default, including explicit ['gemini']) matches legacy rows.
33864
+ seedProviders == null ? isNull(discoverySessions.seedProviders) : eq35(discoverySessions.seedProviders, seedProviders),
33844
33865
  inArray12(discoverySessions.status, [
33845
33866
  DiscoverySessionStatuses.queued,
33846
33867
  DiscoverySessionStatuses.seeding,
@@ -33860,6 +33881,7 @@ async function discoveryRoutes(app, opts) {
33860
33881
  status: DiscoverySessionStatuses.queued,
33861
33882
  icpDescription,
33862
33883
  buyerDescription: parsed.data.buyerDescription ?? null,
33884
+ seedProviders,
33863
33885
  locations,
33864
33886
  dedupThreshold: parsed.data.dedupThreshold,
33865
33887
  competitorMap: [],
@@ -33896,6 +33918,7 @@ async function discoveryRoutes(app, opts) {
33896
33918
  projectId: project.id,
33897
33919
  icpDescription,
33898
33920
  buyerDescription: parsed.data.buyerDescription,
33921
+ seedProviders: seedProviders ?? void 0,
33899
33922
  dedupThreshold: parsed.data.dedupThreshold,
33900
33923
  maxProbes: parsed.data.maxProbes,
33901
33924
  probeConcurrency: parsed.data.probeConcurrency,
@@ -34154,6 +34177,8 @@ function serializeSession(row) {
34154
34177
  buyerDescription: row.buyerDescription ?? null,
34155
34178
  locations: row.locations ?? null,
34156
34179
  seedRawCandidates: row.seedRawCandidates ?? null,
34180
+ seedProviders: row.seedProviders ?? null,
34181
+ seedProviderCounts: row.seedProviderCounts ?? null,
34157
34182
  dedupClusterMinSims: row.dedupClusterMinSims ?? null,
34158
34183
  dedupBandPairFraction: row.dedupBandPairFraction ?? null,
34159
34184
  dedupPairsTotal: row.dedupPairsTotal ?? null,
@@ -34266,6 +34291,7 @@ async function executeDiscovery(opts) {
34266
34291
  project: opts.project,
34267
34292
  icpDescription: opts.icpDescription,
34268
34293
  buyerDescription: opts.buyerDescription,
34294
+ seedProviders: opts.seedProviders,
34269
34295
  locations: opts.locations ?? []
34270
34296
  });
34271
34297
  const { kept: unbrandedCandidates, droppedBranded } = filterBrandedSeedCandidates({
@@ -34302,6 +34328,8 @@ async function executeDiscovery(opts) {
34302
34328
  // live session a replayable fixture; the similarity stats are the data
34303
34329
  // the 0.95-threshold decision was missing. No gate reads any of these.
34304
34330
  seedRawCandidates: seedResult.candidates,
34331
+ seedProviders: opts.seedProviders ?? null,
34332
+ seedProviderCounts: seedResult.providerCounts ?? null,
34305
34333
  dedupClusterMinSims: dedupStats.perClusterMinSimilarity,
34306
34334
  dedupBandPairFraction: dedupStats.bandPairFraction,
34307
34335
  dedupPairsTotal: dedupStats.pairsTotal,
@@ -25,7 +25,7 @@ import {
25
25
  trafficConnectVercelRequestSchema,
26
26
  trafficConnectWordpressRequestSchema,
27
27
  trafficEventKindSchema
28
- } from "./chunk-WXAHSQOX.js";
28
+ } from "./chunk-YQ4KOC5Z.js";
29
29
 
30
30
  // src/config.ts
31
31
  import fs from "fs";
@@ -5566,6 +5566,7 @@ var discoveryRunInputSchema = z2.object({
5566
5566
  // upper bound; this just clarifies the meaning of each knob.
5567
5567
  icpDescription: z2.string().min(1).optional().describe("Free-text ICP description. If omitted, the project must already have spec.icpDescription stored."),
5568
5568
  buyerDescription: z2.string().min(1).optional().describe("Who evaluates or buys the offering, separate from the ICP. When present, every generated query is anchored on this buyer."),
5569
+ seedProviders: z2.array(z2.enum(["gemini", "openai"])).min(1).optional().describe('Which providers generate seed candidates. Omit for the Gemini-only default; ["gemini","openai"] merges both phrasing distributions before dedup.'),
5569
5570
  dedupThreshold: z2.number().min(0).max(1).optional().describe("Cosine similarity threshold for clustering seed candidates. Defaults to 0.85. Lower values dedupe more aggressively."),
5570
5571
  maxProbes: z2.number().int().positive().max(DISCOVERY_MAX_PROBES_CAP).optional().describe(`Max canonical queries to probe in this session. Default 100, hard cap ${DISCOVERY_MAX_PROBES_CAP}.`),
5571
5572
  probeConcurrency: z2.number().int().min(1).max(DISCOVERY_PROBE_CONCURRENCY_CAP).optional().describe(`How many probes may run in parallel. Default 1 (strictly serial), hard cap ${DISCOVERY_PROBE_CONCURRENCY_CAP}. Probe rows are persisted in canonical order regardless of concurrency, so this only shortens wall-clock time.`)
@@ -2241,6 +2241,11 @@ var discoverySessionDtoSchema = z17.object({
2241
2241
  /** Dedup calibration: fraction of all pairs in the ambiguous 0.90-0.97 band. */
2242
2242
  dedupBandPairFraction: z17.number().nullable().optional(),
2243
2243
  dedupPairsTotal: z17.number().int().nullable().optional(),
2244
+ /** Seed provider set the session ran with (canonical order); null = legacy /
2245
+ * Gemini-only default. */
2246
+ seedProviders: z17.array(z17.string()).nullable().optional(),
2247
+ /** Raw candidate count contributed per seed provider. */
2248
+ seedProviderCounts: z17.record(z17.string(), z17.number().int()).nullable().optional(),
2244
2249
  dedupThreshold: z17.number().nullable().optional(),
2245
2250
  probeCount: z17.number().int().nullable().optional(),
2246
2251
  citedCount: z17.number().int().nullable().default(null),
@@ -2317,6 +2322,8 @@ function containsWholeToken(normalized, token) {
2317
2322
  }
2318
2323
  return false;
2319
2324
  }
2325
+ var DISCOVERY_SEED_PROVIDERS = ["gemini", "openai"];
2326
+ var discoverySeedProviderSchema = z17.enum(DISCOVERY_SEED_PROVIDERS);
2320
2327
  var discoveryRunRequestSchema = z17.object({
2321
2328
  icpDescription: z17.string().min(1).optional(),
2322
2329
  /**
@@ -2326,6 +2333,14 @@ var discoveryRunRequestSchema = z17.object({
2326
2333
  * generic provider comparisons.
2327
2334
  */
2328
2335
  buyerDescription: z17.string().min(1).optional(),
2336
+ /**
2337
+ * Which providers generate seed candidates. Omitted = Gemini-only (the
2338
+ * historical behaviour). Canonicalized (deduped + sorted) so the value is
2339
+ * stable for session-identity comparison. Part of the consolidation
2340
+ * IDENTITY: a different provider set produces a different phrasing
2341
+ * distribution, so it must never reuse another set's session.
2342
+ */
2343
+ seedProviders: z17.array(discoverySeedProviderSchema).min(1).transform((arr) => [...new Set(arr)].sort()).optional(),
2329
2344
  dedupThreshold: z17.number().min(0).max(1).optional(),
2330
2345
  maxProbes: z17.number().int().positive().max(DISCOVERY_MAX_PROBES_CAP).optional(),
2331
2346
  /**
package/dist/cli.js CHANGED
@@ -29,7 +29,7 @@ import {
29
29
  setTelemetrySource,
30
30
  showFirstRunNotice,
31
31
  trackEvent
32
- } from "./chunk-YEOLQT5S.js";
32
+ } from "./chunk-6PHBWPPN.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-QZQLZL3C.js";
49
+ } from "./chunk-X4LLTNQZ.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-3HKBUYIY.js";
57
+ } from "./chunk-JGRVQJHX.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-WXAHSQOX.js";
83
+ } from "./chunk-YQ4KOC5Z.js";
84
84
 
85
85
  // src/cli.ts
86
86
  import { pathToFileURL } from "url";
@@ -1656,6 +1656,7 @@ function buildRunBody(opts, icpDescription) {
1656
1656
  const body = {};
1657
1657
  if (icpDescription) body.icpDescription = icpDescription;
1658
1658
  if (opts.buyer !== void 0 && opts.buyer.trim() !== "") body.buyerDescription = opts.buyer;
1659
+ if (opts.seedProviders && opts.seedProviders.length > 0) body.seedProviders = opts.seedProviders;
1659
1660
  if (opts.dedupThreshold !== void 0) body.dedupThreshold = opts.dedupThreshold;
1660
1661
  if (opts.maxProbes !== void 0) body.maxProbes = opts.maxProbes;
1661
1662
  if (opts.probeConcurrency !== void 0) body.probeConcurrency = opts.probeConcurrency;
@@ -2058,10 +2059,11 @@ Usage: ${usage}`,
2058
2059
  var DISCOVER_CLI_COMMANDS = [
2059
2060
  {
2060
2061
  path: ["discover", "run"],
2061
- usage: 'canonry discover run <project> [--icp "..."] [--buyer "..."] [--icp-angle "..."] [--locations michigan,florida] [--dedup-threshold 0.95] [--max-probes 100] [--probe-concurrency 3] [--wait] [--format json]',
2062
+ usage: 'canonry discover run <project> [--icp "..."] [--buyer "..."] [--seed-provider gemini --seed-provider openai] [--icp-angle "..."] [--locations michigan,florida] [--dedup-threshold 0.95] [--max-probes 100] [--probe-concurrency 3] [--wait] [--format json]',
2062
2063
  options: {
2063
2064
  icp: stringOption(),
2064
2065
  buyer: stringOption(),
2066
+ "seed-provider": multiStringOption(),
2065
2067
  "icp-angle": multiStringOption(),
2066
2068
  locations: multiStringOption(),
2067
2069
  "dedup-threshold": stringOption(),
@@ -2070,11 +2072,12 @@ var DISCOVER_CLI_COMMANDS = [
2070
2072
  wait: { type: "boolean", default: false }
2071
2073
  },
2072
2074
  run: async (input) => {
2073
- const usage = 'canonry discover run <project> [--icp "..."] [--buyer "..."] [--icp-angle "..."] [--locations michigan,florida] [--dedup-threshold 0.95] [--max-probes 100] [--probe-concurrency 3] [--wait] [--format json]';
2075
+ const usage = 'canonry discover run <project> [--icp "..."] [--buyer "..."] [--seed-provider gemini --seed-provider openai] [--icp-angle "..."] [--locations michigan,florida] [--dedup-threshold 0.95] [--max-probes 100] [--probe-concurrency 3] [--wait] [--format json]';
2074
2076
  const project = requireProject(input, "discover.run", usage);
2075
2077
  await discoverRun(project, {
2076
2078
  icp: getString(input.values, "icp"),
2077
2079
  buyer: getString(input.values, "buyer"),
2080
+ seedProviders: getStringArray(input.values, "seed-provider"),
2078
2081
  icpAngles: getStringArray(input.values, "icp-angle"),
2079
2082
  locations: parseLocationsOption(input.values),
2080
2083
  dedupThreshold: parseFloatOption(input.values, "dedup-threshold", usage),
@@ -2095,10 +2098,11 @@ var DISCOVER_CLI_COMMANDS = [
2095
2098
  },
2096
2099
  {
2097
2100
  path: ["discover", "seed"],
2098
- usage: 'canonry discover seed <project> [--icp "..."] [--buyer "..."] [--icp-angle "..."] [--locations michigan,florida] [--dedup-threshold 0.95] [--max-probes 100] [--probe-concurrency 3] [--wait] [--format json]',
2101
+ usage: 'canonry discover seed <project> [--icp "..."] [--buyer "..."] [--seed-provider gemini --seed-provider openai] [--icp-angle "..."] [--locations michigan,florida] [--dedup-threshold 0.95] [--max-probes 100] [--probe-concurrency 3] [--wait] [--format json]',
2099
2102
  options: {
2100
2103
  icp: stringOption(),
2101
2104
  buyer: stringOption(),
2105
+ "seed-provider": multiStringOption(),
2102
2106
  "icp-angle": multiStringOption(),
2103
2107
  locations: multiStringOption(),
2104
2108
  "dedup-threshold": stringOption(),
@@ -2107,11 +2111,12 @@ var DISCOVER_CLI_COMMANDS = [
2107
2111
  wait: { type: "boolean", default: false }
2108
2112
  },
2109
2113
  run: async (input) => {
2110
- const usage = 'canonry discover seed <project> [--icp "..."] [--buyer "..."] [--icp-angle "..."] [--locations michigan,florida] [--dedup-threshold 0.95] [--max-probes 100] [--probe-concurrency 3] [--wait] [--format json]';
2114
+ const usage = 'canonry discover seed <project> [--icp "..."] [--buyer "..."] [--seed-provider gemini --seed-provider openai] [--icp-angle "..."] [--locations michigan,florida] [--dedup-threshold 0.95] [--max-probes 100] [--probe-concurrency 3] [--wait] [--format json]';
2111
2115
  const project = requireProject(input, "discover.seed", usage);
2112
2116
  await discoverSeed(project, {
2113
2117
  icp: getString(input.values, "icp"),
2114
2118
  buyer: getString(input.values, "buyer"),
2119
+ seedProviders: getStringArray(input.values, "seed-provider"),
2115
2120
  icpAngles: getStringArray(input.values, "icp-angle"),
2116
2121
  locations: parseLocationsOption(input.values),
2117
2122
  dedupThreshold: parseFloatOption(input.values, "dedup-threshold", usage),
package/dist/index.js CHANGED
@@ -1,11 +1,11 @@
1
1
  import {
2
2
  createServer
3
- } from "./chunk-YEOLQT5S.js";
3
+ } from "./chunk-6PHBWPPN.js";
4
4
  import {
5
5
  loadConfig
6
- } from "./chunk-QZQLZL3C.js";
7
- import "./chunk-3HKBUYIY.js";
8
- import "./chunk-WXAHSQOX.js";
6
+ } from "./chunk-X4LLTNQZ.js";
7
+ import "./chunk-JGRVQJHX.js";
8
+ import "./chunk-YQ4KOC5Z.js";
9
9
  export {
10
10
  createServer,
11
11
  loadConfig
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  IntelligenceService
3
- } from "./chunk-3HKBUYIY.js";
4
- import "./chunk-WXAHSQOX.js";
3
+ } from "./chunk-JGRVQJHX.js";
4
+ import "./chunk-YQ4KOC5Z.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-QZQLZL3C.js";
6
+ } from "./chunk-X4LLTNQZ.js";
7
7
  import {
8
8
  isReadOnlyKey
9
- } from "./chunk-WXAHSQOX.js";
9
+ } from "./chunk-YQ4KOC5Z.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.109.0",
3
+ "version": "4.110.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,26 +65,26 @@
65
65
  "@types/node-cron": "^3.0.11",
66
66
  "tsup": "^8.5.1",
67
67
  "tsx": "^4.19.0",
68
- "@ainyc/canonry-api-routes": "0.0.0",
69
- "@ainyc/canonry-contracts": "0.0.0",
70
68
  "@ainyc/canonry-config": "0.0.0",
71
69
  "@ainyc/canonry-api-client": "0.0.0",
70
+ "@ainyc/canonry-api-routes": "0.0.0",
71
+ "@ainyc/canonry-contracts": "0.0.0",
72
72
  "@ainyc/canonry-db": "0.0.0",
73
73
  "@ainyc/canonry-integration-bing": "0.0.0",
74
74
  "@ainyc/canonry-integration-openai-ads": "0.0.0",
75
- "@ainyc/canonry-integration-commoncrawl": "0.0.0",
76
75
  "@ainyc/canonry-integration-cloud-run": "0.0.0",
76
+ "@ainyc/canonry-integration-commoncrawl": "0.0.0",
77
77
  "@ainyc/canonry-integration-google": "0.0.0",
78
+ "@ainyc/canonry-integration-traffic": "0.0.0",
78
79
  "@ainyc/canonry-integration-google-business-profile": "0.0.0",
79
- "@ainyc/canonry-integration-google-places": "0.0.0",
80
80
  "@ainyc/canonry-integration-wordpress": "0.0.0",
81
- "@ainyc/canonry-integration-traffic": "0.0.0",
82
81
  "@ainyc/canonry-intelligence": "0.0.0",
83
- "@ainyc/canonry-provider-cdp": "0.0.0",
82
+ "@ainyc/canonry-integration-google-places": "0.0.0",
84
83
  "@ainyc/canonry-provider-claude": "0.0.0",
84
+ "@ainyc/canonry-provider-cdp": "0.0.0",
85
+ "@ainyc/canonry-provider-gemini": "0.0.0",
85
86
  "@ainyc/canonry-provider-local": "0.0.0",
86
87
  "@ainyc/canonry-provider-openai": "0.0.0",
87
- "@ainyc/canonry-provider-gemini": "0.0.0",
88
88
  "@ainyc/canonry-provider-perplexity": "0.0.0"
89
89
  },
90
90
  "scripts": {