@ainyc/canonry 4.32.0 → 4.33.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,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-CUMjedc6.js"></script>
15
+ <script type="module" crossorigin src="./assets/index-47V0U52s.js"></script>
16
16
  <link rel="stylesheet" crossorigin href="./assets/index-CNKAwZMB.css">
17
17
  </head>
18
18
  <body>
@@ -22,7 +22,7 @@ import {
22
22
  trafficConnectVercelRequestSchema,
23
23
  trafficConnectWordpressRequestSchema,
24
24
  trafficEventKindSchema
25
- } from "./chunk-5M4PP6P4.js";
25
+ } from "./chunk-XW3F5EEW.js";
26
26
 
27
27
  // src/config.ts
28
28
  import fs from "fs";
@@ -8,7 +8,7 @@ import {
8
8
  categoryLabel,
9
9
  determineAnswerMentioned,
10
10
  normalizeProjectDomain
11
- } from "./chunk-5M4PP6P4.js";
11
+ } from "./chunk-XW3F5EEW.js";
12
12
 
13
13
  // src/intelligence-service.ts
14
14
  import { eq, desc, asc, and, or, inArray } from "drizzle-orm";
@@ -5,7 +5,7 @@ import {
5
5
  loadConfig,
6
6
  loadConfigRaw,
7
7
  saveConfigPatch
8
- } from "./chunk-LVX5TOYA.js";
8
+ } from "./chunk-5EBN7736.js";
9
9
  import {
10
10
  DEFAULT_RUN_HISTORY_LIMIT,
11
11
  IntelligenceService,
@@ -70,7 +70,7 @@ import {
70
70
  schedules,
71
71
  trafficSources,
72
72
  usageCounters
73
- } from "./chunk-LUAJVZVZ.js";
73
+ } from "./chunk-BJXHETQW.js";
74
74
  import {
75
75
  AGENT_MEMORY_VALUE_MAX_BYTES,
76
76
  AGENT_PROVIDER_IDS,
@@ -162,6 +162,7 @@ import {
162
162
  reportHorizonLabel,
163
163
  reportSeverityLabel,
164
164
  resolveConfigSpecQueries,
165
+ resolveLocations,
165
166
  resolveSnapshotRequestQueries,
166
167
  runInProgress,
167
168
  runNotCancellable,
@@ -178,7 +179,7 @@ import {
178
179
  visibilityStateFromAnswerMentioned,
179
180
  windowCutoff,
180
181
  wordpressEnvSchema
181
- } from "./chunk-5M4PP6P4.js";
182
+ } from "./chunk-XW3F5EEW.js";
182
183
 
183
184
  // src/telemetry.ts
184
185
  import crypto from "crypto";
@@ -10399,7 +10400,12 @@ var routeCatalog = [
10399
10400
  properties: {
10400
10401
  icpDescription: { type: "string", description: "Free-text ICP. Required if the project does not have spec.icpDescription stored." },
10401
10402
  dedupThreshold: { type: "number", description: "Cosine similarity threshold for clustering. Defaults to 0.85." },
10402
- maxProbes: { type: "integer", description: "Max canonical queries to probe in this session. Default 100, hard cap 500." }
10403
+ maxProbes: { type: "integer", description: "Max canonical queries to probe in this session. Default 100, hard cap 500." },
10404
+ locations: {
10405
+ type: "array",
10406
+ items: { type: "string" },
10407
+ description: "Optional override of the project location labels used to geo-constrain seed generation. Each label must match a configured project location; an unknown label is a 400. Omit to use every project location."
10408
+ }
10403
10409
  }
10404
10410
  }
10405
10411
  }
@@ -20022,6 +20028,10 @@ async function discoveryRoutes(app, opts) {
20022
20028
  "icpDescription is required. Pass it in the request body or store it on the project (spec.icpDescription)."
20023
20029
  );
20024
20030
  }
20031
+ const locations = resolveLocations(
20032
+ parseJsonColumn(project.locations, []),
20033
+ parsed.data.locations
20034
+ );
20025
20035
  if (!opts.onDiscoveryRunRequested) {
20026
20036
  throw validationError("Discovery is not available on this deployment.", {
20027
20037
  reason: "no-discovery-handler"
@@ -20063,7 +20073,8 @@ async function discoveryRoutes(app, opts) {
20063
20073
  projectId: project.id,
20064
20074
  icpDescription,
20065
20075
  dedupThreshold: parsed.data.dedupThreshold,
20066
- maxProbes: parsed.data.maxProbes
20076
+ maxProbes: parsed.data.maxProbes,
20077
+ locations
20067
20078
  });
20068
20079
  return reply.status(201).send({ runId, sessionId, status: "running" });
20069
20080
  });
@@ -20343,7 +20354,8 @@ async function executeDiscovery(opts) {
20343
20354
  }).where(eq26(discoverySessions.id, opts.sessionId)).run();
20344
20355
  const seedResult = await opts.deps.seed({
20345
20356
  project: opts.project,
20346
- icpDescription: opts.icpDescription
20357
+ icpDescription: opts.icpDescription,
20358
+ locations: opts.locations ?? []
20347
20359
  });
20348
20360
  const rawCandidates = dedupeStrings(seedResult.candidates);
20349
20361
  const seedCountRaw = rawCandidates.length;
@@ -24984,6 +24996,7 @@ async function executeDiscoveryRun(opts) {
24984
24996
  icpDescription: opts.icpDescription,
24985
24997
  dedupThreshold: opts.dedupThreshold,
24986
24998
  maxProbes: opts.maxProbes,
24999
+ locations: opts.locations,
24987
25000
  deps
24988
25001
  });
24989
25002
  writeDiscoveryInsight(opts.db, {
@@ -25141,12 +25154,32 @@ function extractClassificationCategory(line) {
25141
25154
  }
25142
25155
  return null;
25143
25156
  }
25157
+ function formatLocationLine(location) {
25158
+ return [location.city, location.region, location.country].map((part) => part.trim()).filter(Boolean).join(", ");
25159
+ }
25160
+ function buildLocationConstraint(locations) {
25161
+ if (locations.length === 0) return [];
25162
+ const formatted = locations.map(formatLocationLine);
25163
+ if (locations.length === 1) {
25164
+ return [
25165
+ `The business serves ${formatted[0]}. Every query must be relevant to that service area \u2014 work the city or region into the query the way a real searcher would.`
25166
+ ];
25167
+ }
25168
+ const perLocation = Math.max(1, Math.floor(DEFAULT_SEED_COUNT / locations.length));
25169
+ return [
25170
+ "The business serves these locations:",
25171
+ ...formatted.map((line) => ` - ${line}`),
25172
+ `Generate at least ${perLocation} queries for EACH service area listed above so coverage stays balanced \u2014 do not let one area dominate. Every query must be relevant to at least one of these service areas, working the city or region into the query the way a real searcher would.`
25173
+ ];
25174
+ }
25144
25175
  function buildSeedPrompt(input) {
25176
+ const locationConstraint = buildLocationConstraint(input.locations ?? []);
25145
25177
  return [
25146
25178
  "You are an AEO (Answer Engine Optimization) analyst expanding a tracked-query basket for a customer.",
25147
25179
  "",
25148
25180
  `Customer: ${input.project.name} (domains: ${input.project.canonicalDomains.join(", ")})`,
25149
25181
  `ICP: ${input.icpDescription}`,
25182
+ ...locationConstraint.length > 0 ? ["", ...locationConstraint] : [],
25150
25183
  "",
25151
25184
  "Brainstorm a wide set of queries a member of this ICP would type into an AI answer engine (Gemini, ChatGPT, Perplexity) when they are about to make a decision in this space. Aim for 30+ candidates covering:",
25152
25185
  ' - Comparison queries ("best X for Y")',
@@ -28308,7 +28341,8 @@ async function createServer(opts) {
28308
28341
  projectId: input.projectId,
28309
28342
  icpDescription: input.icpDescription,
28310
28343
  dedupThreshold: input.dedupThreshold,
28311
- maxProbes: input.maxProbes
28344
+ maxProbes: input.maxProbes,
28345
+ locations: input.locations
28312
28346
  }).then(() => runCoordinator.onRunCompleted(input.runId, input.projectId)).catch((err) => {
28313
28347
  app.log.error({ runId: input.runId, err }, "Discovery run failed");
28314
28348
  });
@@ -300,6 +300,74 @@ var notificationCreateRequestSchema = z3.object({
300
300
 
301
301
  // ../contracts/src/project.ts
302
302
  import { z as z4 } from "zod";
303
+
304
+ // ../contracts/src/errors.ts
305
+ var AppError = class extends Error {
306
+ code;
307
+ statusCode;
308
+ details;
309
+ constructor(code, message, statusCode, details) {
310
+ super(message);
311
+ this.name = "AppError";
312
+ this.code = code;
313
+ this.statusCode = statusCode;
314
+ this.details = details;
315
+ }
316
+ toJSON() {
317
+ return {
318
+ error: {
319
+ code: this.code,
320
+ message: this.message,
321
+ ...this.details ? { details: this.details } : {}
322
+ }
323
+ };
324
+ }
325
+ };
326
+ function notFound(entity, id) {
327
+ return new AppError("NOT_FOUND", `${entity} '${id}' not found`, 404);
328
+ }
329
+ function validationError(message, details) {
330
+ return new AppError("VALIDATION_ERROR", message, 400, details);
331
+ }
332
+ function authRequired() {
333
+ return new AppError("AUTH_REQUIRED", "Authentication required", 401);
334
+ }
335
+ function authInvalid() {
336
+ return new AppError("AUTH_INVALID", "Invalid API key", 401);
337
+ }
338
+ function providerError(message, details) {
339
+ return new AppError("PROVIDER_ERROR", message, 502, details);
340
+ }
341
+ function runInProgress(projectName) {
342
+ return new AppError("RUN_IN_PROGRESS", `A run is already in progress for '${projectName}'`, 409);
343
+ }
344
+ function runNotCancellable(runId, status) {
345
+ return new AppError("RUN_NOT_CANCELLABLE", `Run '${runId}' is already in terminal state '${status}' and cannot be cancelled`, 409);
346
+ }
347
+ function unsupportedKind(kind) {
348
+ return new AppError("UNSUPPORTED_KIND", `Kind '${kind}' is not supported in this version`, 400);
349
+ }
350
+ function notImplemented(message) {
351
+ return new AppError("NOT_IMPLEMENTED", message, 501);
352
+ }
353
+ function deliveryFailed(message) {
354
+ return new AppError("DELIVERY_FAILED", message, 502);
355
+ }
356
+ function agentBusy(projectName) {
357
+ return new AppError(
358
+ "AGENT_BUSY",
359
+ `Aero is already running a turn for '${projectName}'. Retry after the current turn settles.`,
360
+ 409
361
+ );
362
+ }
363
+ function missingDependency(message, details) {
364
+ return new AppError("MISSING_DEPENDENCY", message, 422, details);
365
+ }
366
+ function internalError(message, details) {
367
+ return new AppError("INTERNAL_ERROR", message, 500, details);
368
+ }
369
+
370
+ // ../contracts/src/project.ts
303
371
  var configSourceSchema = z4.enum(["cli", "api", "config-file"]);
304
372
  function findDuplicateLocationLabels(locations) {
305
373
  const seen = /* @__PURE__ */ new Set();
@@ -317,6 +385,26 @@ function hasLocationLabel(locations, label) {
317
385
  if (!label) return true;
318
386
  return locations.some((location) => location.label === label);
319
387
  }
388
+ function resolveLocations(projectLocations, requestedLabels) {
389
+ const normalizedRequest = (requestedLabels ?? []).map((label) => label.trim()).filter((label) => label.length > 0);
390
+ if (normalizedRequest.length === 0) return [...projectLocations];
391
+ const byLabel = new Map(projectLocations.map((loc) => [loc.label.toLowerCase(), loc]));
392
+ const resolved = [];
393
+ const seen = /* @__PURE__ */ new Set();
394
+ for (const label of normalizedRequest) {
395
+ const key = label.toLowerCase();
396
+ if (seen.has(key)) continue;
397
+ const match = byLabel.get(key);
398
+ if (!match) {
399
+ throw validationError(
400
+ `Location "${label}" is not configured for this project. Add it to the project's locations or omit the locations override.`
401
+ );
402
+ }
403
+ seen.add(key);
404
+ resolved.push(match);
405
+ }
406
+ return resolved;
407
+ }
320
408
  var projectUpsertRequestSchema = z4.object({
321
409
  displayName: z4.string().min(1),
322
410
  canonicalDomain: z4.string().min(1),
@@ -542,72 +630,6 @@ function resolveConfigSpecQueries(spec) {
542
630
  return spec.queries ?? spec.keywords ?? [];
543
631
  }
544
632
 
545
- // ../contracts/src/errors.ts
546
- var AppError = class extends Error {
547
- code;
548
- statusCode;
549
- details;
550
- constructor(code, message, statusCode, details) {
551
- super(message);
552
- this.name = "AppError";
553
- this.code = code;
554
- this.statusCode = statusCode;
555
- this.details = details;
556
- }
557
- toJSON() {
558
- return {
559
- error: {
560
- code: this.code,
561
- message: this.message,
562
- ...this.details ? { details: this.details } : {}
563
- }
564
- };
565
- }
566
- };
567
- function notFound(entity, id) {
568
- return new AppError("NOT_FOUND", `${entity} '${id}' not found`, 404);
569
- }
570
- function validationError(message, details) {
571
- return new AppError("VALIDATION_ERROR", message, 400, details);
572
- }
573
- function authRequired() {
574
- return new AppError("AUTH_REQUIRED", "Authentication required", 401);
575
- }
576
- function authInvalid() {
577
- return new AppError("AUTH_INVALID", "Invalid API key", 401);
578
- }
579
- function providerError(message, details) {
580
- return new AppError("PROVIDER_ERROR", message, 502, details);
581
- }
582
- function runInProgress(projectName) {
583
- return new AppError("RUN_IN_PROGRESS", `A run is already in progress for '${projectName}'`, 409);
584
- }
585
- function runNotCancellable(runId, status) {
586
- return new AppError("RUN_NOT_CANCELLABLE", `Run '${runId}' is already in terminal state '${status}' and cannot be cancelled`, 409);
587
- }
588
- function unsupportedKind(kind) {
589
- return new AppError("UNSUPPORTED_KIND", `Kind '${kind}' is not supported in this version`, 400);
590
- }
591
- function notImplemented(message) {
592
- return new AppError("NOT_IMPLEMENTED", message, 501);
593
- }
594
- function deliveryFailed(message) {
595
- return new AppError("DELIVERY_FAILED", message, 502);
596
- }
597
- function agentBusy(projectName) {
598
- return new AppError(
599
- "AGENT_BUSY",
600
- `Aero is already running a turn for '${projectName}'. Retry after the current turn settles.`,
601
- 409
602
- );
603
- }
604
- function missingDependency(message, details) {
605
- return new AppError("MISSING_DEPENDENCY", message, 422, details);
606
- }
607
- function internalError(message, details) {
608
- return new AppError("INTERNAL_ERROR", message, 500, details);
609
- }
610
-
611
633
  // ../contracts/src/google.ts
612
634
  import { z as z6 } from "zod";
613
635
  var googleConnectionTypeSchema = z6.enum(["gsc", "ga4"]);
@@ -2442,7 +2464,15 @@ var DISCOVERY_MAX_PROBES_CAP = 500;
2442
2464
  var discoveryRunRequestSchema = z21.object({
2443
2465
  icpDescription: z21.string().min(1).optional(),
2444
2466
  dedupThreshold: z21.number().min(0).max(1).optional(),
2445
- maxProbes: z21.number().int().positive().max(DISCOVERY_MAX_PROBES_CAP).optional()
2467
+ maxProbes: z21.number().int().positive().max(DISCOVERY_MAX_PROBES_CAP).optional(),
2468
+ /**
2469
+ * Optional override of the project's location labels, constraining seed
2470
+ * generation to a subset of the configured service areas. Each label must
2471
+ * match a configured project location (resolved server-side via
2472
+ * `resolveLocations`). Omitted means "use every project location" — a
2473
+ * project with no locations is unaffected.
2474
+ */
2475
+ locations: z21.array(z21.string().min(1)).optional()
2446
2476
  });
2447
2477
  var discoveryPromoteRequestSchema = z21.object({
2448
2478
  buckets: z21.array(discoveryBucketSchema).min(1).optional(),
@@ -2614,20 +2644,6 @@ export {
2614
2644
  getProviderLocationHandling,
2615
2645
  notificationEventSchema,
2616
2646
  notificationCreateRequestSchema,
2617
- findDuplicateLocationLabels,
2618
- hasLocationLabel,
2619
- projectUpsertRequestSchema,
2620
- queryBatchRequestSchema,
2621
- keywordBatchRequestSchema,
2622
- queryGenerateRequestSchema,
2623
- keywordGenerateRequestSchema,
2624
- competitorBatchRequestSchema,
2625
- normalizeProjectDomain,
2626
- registrableDomain,
2627
- brandLabelFromDomain,
2628
- effectiveDomains,
2629
- projectConfigSchema,
2630
- resolveConfigSpecQueries,
2631
2647
  AppError,
2632
2648
  notFound,
2633
2649
  validationError,
@@ -2642,6 +2658,21 @@ export {
2642
2658
  agentBusy,
2643
2659
  missingDependency,
2644
2660
  internalError,
2661
+ findDuplicateLocationLabels,
2662
+ hasLocationLabel,
2663
+ resolveLocations,
2664
+ projectUpsertRequestSchema,
2665
+ queryBatchRequestSchema,
2666
+ keywordBatchRequestSchema,
2667
+ queryGenerateRequestSchema,
2668
+ keywordGenerateRequestSchema,
2669
+ competitorBatchRequestSchema,
2670
+ normalizeProjectDomain,
2671
+ registrableDomain,
2672
+ brandLabelFromDomain,
2673
+ effectiveDomains,
2674
+ projectConfigSchema,
2675
+ resolveConfigSpecQueries,
2645
2676
  wordpressEnvSchema,
2646
2677
  AgentProviderIds,
2647
2678
  AGENT_PROVIDER_IDS,
package/dist/cli.js CHANGED
@@ -20,7 +20,7 @@ import {
20
20
  setTelemetrySource,
21
21
  showFirstRunNotice,
22
22
  trackEvent
23
- } from "./chunk-7I65IXVU.js";
23
+ } from "./chunk-JJHBPITI.js";
24
24
  import {
25
25
  CliError,
26
26
  EXIT_SYSTEM_ERROR,
@@ -36,7 +36,7 @@ import {
36
36
  saveConfig,
37
37
  saveConfigPatch,
38
38
  usageError
39
- } from "./chunk-LVX5TOYA.js";
39
+ } from "./chunk-5EBN7736.js";
40
40
  import {
41
41
  apiKeys,
42
42
  competitors,
@@ -49,7 +49,7 @@ import {
49
49
  queries,
50
50
  querySnapshots,
51
51
  runs
52
- } from "./chunk-LUAJVZVZ.js";
52
+ } from "./chunk-BJXHETQW.js";
53
53
  import {
54
54
  CcReleaseSyncStatuses,
55
55
  CheckScopes,
@@ -71,7 +71,7 @@ import {
71
71
  providerQuotaPolicySchema,
72
72
  resolveProviderInput,
73
73
  skillsClientSchema
74
- } from "./chunk-5M4PP6P4.js";
74
+ } from "./chunk-XW3F5EEW.js";
75
75
 
76
76
  // src/cli.ts
77
77
  import { pathToFileURL } from "url";
@@ -623,7 +623,7 @@ function readStoredGroundingSources(rawResponse) {
623
623
  return result;
624
624
  }
625
625
  async function backfillInsightsCommand(project, opts) {
626
- const { IntelligenceService } = await import("./intelligence-service-RSRWDBHS.js");
626
+ const { IntelligenceService } = await import("./intelligence-service-XKOUBRCE.js");
627
627
  const config = loadConfig();
628
628
  const db = createClient(config.database);
629
629
  migrate(db);
@@ -1971,6 +1971,7 @@ function buildRunBody(opts, icpDescription) {
1971
1971
  if (icpDescription) body.icpDescription = icpDescription;
1972
1972
  if (opts.dedupThreshold !== void 0) body.dedupThreshold = opts.dedupThreshold;
1973
1973
  if (opts.maxProbes !== void 0) body.maxProbes = opts.maxProbes;
1974
+ if (opts.locations && opts.locations.length > 0) body.locations = opts.locations;
1974
1975
  return body;
1975
1976
  }
1976
1977
  function resolveIcpAngles(opts) {
@@ -2241,6 +2242,12 @@ Usage: ${usage}`, {
2241
2242
  }
2242
2243
  return parsed;
2243
2244
  }
2245
+ function parseLocationsOption(values) {
2246
+ const raw = getStringArray(values, "locations");
2247
+ if (!raw || raw.length === 0) return void 0;
2248
+ const expanded = raw.flatMap((v) => v.split(",")).map((v) => v.trim()).filter(Boolean);
2249
+ return expanded.length > 0 ? expanded : void 0;
2250
+ }
2244
2251
  function parseBucketsOption(values, usage) {
2245
2252
  const raw = getStringArray(values, "bucket");
2246
2253
  if (!raw || raw.length === 0) return void 0;
@@ -2307,20 +2314,22 @@ Usage: ${usage}`,
2307
2314
  var DISCOVER_CLI_COMMANDS = [
2308
2315
  {
2309
2316
  path: ["discover", "run"],
2310
- usage: 'canonry discover run <project> [--icp "..."] [--icp-angle "..."] [--dedup-threshold 0.85] [--max-probes 100] [--wait] [--format json]',
2317
+ usage: 'canonry discover run <project> [--icp "..."] [--icp-angle "..."] [--locations michigan,florida] [--dedup-threshold 0.85] [--max-probes 100] [--wait] [--format json]',
2311
2318
  options: {
2312
2319
  icp: stringOption(),
2313
2320
  "icp-angle": multiStringOption(),
2321
+ locations: multiStringOption(),
2314
2322
  "dedup-threshold": stringOption(),
2315
2323
  "max-probes": stringOption(),
2316
2324
  wait: { type: "boolean", default: false }
2317
2325
  },
2318
2326
  run: async (input) => {
2319
- const usage = 'canonry discover run <project> [--icp "..."] [--icp-angle "..."] [--dedup-threshold 0.85] [--max-probes 100] [--wait] [--format json]';
2327
+ const usage = 'canonry discover run <project> [--icp "..."] [--icp-angle "..."] [--locations michigan,florida] [--dedup-threshold 0.85] [--max-probes 100] [--wait] [--format json]';
2320
2328
  const project = requireProject(input, "discover.run", usage);
2321
2329
  await discoverRun(project, {
2322
2330
  icp: getString(input.values, "icp"),
2323
2331
  icpAngles: getStringArray(input.values, "icp-angle"),
2332
+ locations: parseLocationsOption(input.values),
2324
2333
  dedupThreshold: parseFloatOption(input.values, "dedup-threshold", usage),
2325
2334
  maxProbes: parseIntegerOption(input, "max-probes", {
2326
2335
  command: "discover.run",
@@ -2334,20 +2343,22 @@ var DISCOVER_CLI_COMMANDS = [
2334
2343
  },
2335
2344
  {
2336
2345
  path: ["discover", "seed"],
2337
- usage: 'canonry discover seed <project> [--icp "..."] [--icp-angle "..."] [--dedup-threshold 0.85] [--max-probes 100] [--wait] [--format json]',
2346
+ usage: 'canonry discover seed <project> [--icp "..."] [--icp-angle "..."] [--locations michigan,florida] [--dedup-threshold 0.85] [--max-probes 100] [--wait] [--format json]',
2338
2347
  options: {
2339
2348
  icp: stringOption(),
2340
2349
  "icp-angle": multiStringOption(),
2350
+ locations: multiStringOption(),
2341
2351
  "dedup-threshold": stringOption(),
2342
2352
  "max-probes": stringOption(),
2343
2353
  wait: { type: "boolean", default: false }
2344
2354
  },
2345
2355
  run: async (input) => {
2346
- const usage = 'canonry discover seed <project> [--icp "..."] [--icp-angle "..."] [--dedup-threshold 0.85] [--max-probes 100] [--wait] [--format json]';
2356
+ const usage = 'canonry discover seed <project> [--icp "..."] [--icp-angle "..."] [--locations michigan,florida] [--dedup-threshold 0.85] [--max-probes 100] [--wait] [--format json]';
2347
2357
  const project = requireProject(input, "discover.seed", usage);
2348
2358
  await discoverSeed(project, {
2349
2359
  icp: getString(input.values, "icp"),
2350
2360
  icpAngles: getStringArray(input.values, "icp-angle"),
2361
+ locations: parseLocationsOption(input.values),
2351
2362
  dedupThreshold: parseFloatOption(input.values, "dedup-threshold", usage),
2352
2363
  maxProbes: parseIntegerOption(input, "max-probes", {
2353
2364
  command: "discover.seed",
package/dist/index.js CHANGED
@@ -1,11 +1,11 @@
1
1
  import {
2
2
  createServer
3
- } from "./chunk-7I65IXVU.js";
3
+ } from "./chunk-JJHBPITI.js";
4
4
  import {
5
5
  loadConfig
6
- } from "./chunk-LVX5TOYA.js";
7
- import "./chunk-LUAJVZVZ.js";
8
- import "./chunk-5M4PP6P4.js";
6
+ } from "./chunk-5EBN7736.js";
7
+ import "./chunk-BJXHETQW.js";
8
+ import "./chunk-XW3F5EEW.js";
9
9
  export {
10
10
  createServer,
11
11
  loadConfig
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  IntelligenceService
3
- } from "./chunk-LUAJVZVZ.js";
4
- import "./chunk-5M4PP6P4.js";
3
+ } from "./chunk-BJXHETQW.js";
4
+ import "./chunk-XW3F5EEW.js";
5
5
  export {
6
6
  IntelligenceService
7
7
  };
package/dist/mcp.js CHANGED
@@ -2,8 +2,8 @@ import {
2
2
  CliError,
3
3
  canonryMcpTools,
4
4
  createApiClient
5
- } from "./chunk-LVX5TOYA.js";
6
- import "./chunk-5M4PP6P4.js";
5
+ } from "./chunk-5EBN7736.js";
6
+ import "./chunk-XW3F5EEW.js";
7
7
 
8
8
  // src/mcp/cli.ts
9
9
  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.32.0",
3
+ "version": "4.33.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",
@@ -60,23 +60,23 @@
60
60
  "@types/node-cron": "^3.0.11",
61
61
  "tsup": "^8.5.1",
62
62
  "tsx": "^4.19.0",
63
- "@ainyc/canonry-config": "0.0.0",
64
63
  "@ainyc/canonry-api-routes": "0.0.0",
65
- "@ainyc/canonry-db": "0.0.0",
66
- "@ainyc/canonry-integration-bing": "0.0.0",
64
+ "@ainyc/canonry-contracts": "0.0.0",
67
65
  "@ainyc/canonry-intelligence": "0.0.0",
66
+ "@ainyc/canonry-db": "0.0.0",
68
67
  "@ainyc/canonry-integration-cloud-run": "0.0.0",
69
- "@ainyc/canonry-integration-commoncrawl": "0.0.0",
68
+ "@ainyc/canonry-config": "0.0.0",
69
+ "@ainyc/canonry-integration-bing": "0.0.0",
70
70
  "@ainyc/canonry-integration-google": "0.0.0",
71
- "@ainyc/canonry-integration-traffic": "0.0.0",
71
+ "@ainyc/canonry-integration-commoncrawl": "0.0.0",
72
72
  "@ainyc/canonry-integration-wordpress": "0.0.0",
73
- "@ainyc/canonry-contracts": "0.0.0",
74
73
  "@ainyc/canonry-provider-cdp": "0.0.0",
75
74
  "@ainyc/canonry-provider-gemini": "0.0.0",
76
- "@ainyc/canonry-provider-local": "0.0.0",
75
+ "@ainyc/canonry-integration-traffic": "0.0.0",
77
76
  "@ainyc/canonry-provider-claude": "0.0.0",
77
+ "@ainyc/canonry-provider-perplexity": "0.0.0",
78
78
  "@ainyc/canonry-provider-openai": "0.0.0",
79
- "@ainyc/canonry-provider-perplexity": "0.0.0"
79
+ "@ainyc/canonry-provider-local": "0.0.0"
80
80
  },
81
81
  "scripts": {
82
82
  "build": "tsx scripts/copy-agent-assets.ts && tsup && tsx build-web.ts",