@ainyc/canonry 4.30.0 → 4.32.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 (26) hide show
  1. package/README.md +15 -13
  2. package/assets/agent-workspace/skills/aero/SKILL.md +2 -2
  3. package/assets/agent-workspace/skills/aero/references/aeo-discovery.md +26 -17
  4. package/assets/agent-workspace/skills/aero/references/memory-patterns.md +9 -9
  5. package/assets/agent-workspace/skills/aero/references/orchestration.md +6 -6
  6. package/assets/agent-workspace/skills/aero/references/reporting.md +3 -3
  7. package/assets/agent-workspace/skills/canonry/SKILL.md +5 -3
  8. package/assets/agent-workspace/skills/canonry/references/aeo-analysis.md +9 -9
  9. package/assets/agent-workspace/skills/canonry/references/canonry-cli.md +203 -200
  10. package/assets/agent-workspace/skills/canonry/references/indexing.md +35 -35
  11. package/assets/agent-workspace/skills/canonry/references/server-side-traffic.md +18 -18
  12. package/assets/agent-workspace/skills/canonry/references/wordpress-integration.md +11 -11
  13. package/assets/assets/{index-BnALDZI7.css → index-CNKAwZMB.css} +1 -1
  14. package/assets/assets/index-CUMjedc6.js +302 -0
  15. package/assets/index.html +2 -2
  16. package/dist/{chunk-7UO3EGDB.js → chunk-5M4PP6P4.js} +25 -2
  17. package/dist/{chunk-PTFVEYUX.js → chunk-7I65IXVU.js} +617 -23
  18. package/dist/{chunk-4EDC2P3J.js → chunk-LUAJVZVZ.js} +1 -1
  19. package/dist/{chunk-NIAAHWRF.js → chunk-LVX5TOYA.js} +28 -3
  20. package/dist/cli.js +166 -15
  21. package/dist/index.d.ts +20 -0
  22. package/dist/index.js +4 -4
  23. package/dist/{intelligence-service-ASXADXLF.js → intelligence-service-RSRWDBHS.js} +2 -2
  24. package/dist/mcp.js +2 -2
  25. package/package.json +8 -7
  26. package/assets/assets/index-BYiZYtd9.js +0 -302
@@ -8,7 +8,7 @@ import {
8
8
  categoryLabel,
9
9
  determineAnswerMentioned,
10
10
  normalizeProjectDomain
11
- } from "./chunk-7UO3EGDB.js";
11
+ } from "./chunk-5M4PP6P4.js";
12
12
 
13
13
  // src/intelligence-service.ts
14
14
  import { eq, desc, asc, and, or, inArray } from "drizzle-orm";
@@ -4,6 +4,7 @@ import {
4
4
  DISCOVERY_MAX_PROBES_CAP,
5
5
  competitorBatchRequestSchema,
6
6
  discoveryBucketSchema,
7
+ discoveryCompetitorTypeSchema,
7
8
  discoveryPromoteRequestSchema,
8
9
  discoveryRunRequestSchema,
9
10
  keywordBatchRequestSchema,
@@ -18,9 +19,10 @@ import {
18
19
  schedulableRunKindSchema,
19
20
  scheduleUpsertRequestSchema,
20
21
  trafficConnectCloudRunRequestSchema,
22
+ trafficConnectVercelRequestSchema,
21
23
  trafficConnectWordpressRequestSchema,
22
24
  trafficEventKindSchema
23
- } from "./chunk-7UO3EGDB.js";
25
+ } from "./chunk-5M4PP6P4.js";
24
26
 
25
27
  // src/config.ts
26
28
  import fs from "fs";
@@ -778,6 +780,13 @@ var ApiClient = class {
778
780
  body
779
781
  );
780
782
  }
783
+ async trafficConnectVercel(project, body) {
784
+ return this.request(
785
+ "POST",
786
+ `/projects/${encodeURIComponent(project)}/traffic/connect/vercel`,
787
+ body
788
+ );
789
+ }
781
790
  async trafficSync(project, sourceId, body) {
782
791
  return this.request(
783
792
  "POST",
@@ -1241,6 +1250,10 @@ var trafficConnectWordpressInputSchema = z2.object({
1241
1250
  project: projectNameSchema,
1242
1251
  request: trafficConnectWordpressRequestSchema
1243
1252
  });
1253
+ var trafficConnectVercelInputSchema = z2.object({
1254
+ project: projectNameSchema,
1255
+ request: trafficConnectVercelRequestSchema
1256
+ });
1244
1257
  var trafficSyncInputSchema = z2.object({
1245
1258
  project: projectNameSchema,
1246
1259
  sourceId: z2.string().min(1).describe("Traffic source ID returned by canonry_traffic_connect_cloud_run or canonry_traffic_sources_list."),
@@ -1287,7 +1300,8 @@ var discoveryPromoteInputSchema = z2.object({
1287
1300
  request: discoveryPromoteRequestSchema.extend({
1288
1301
  // Stronger descriptions for the LLM. The base Zod schema enforces the shape.
1289
1302
  buckets: z2.array(discoveryBucketSchema).min(1).optional().describe("Which probe buckets to adopt into the tracked basket. Omitted promotes cited + aspirational; include wasted-surface explicitly for off-ICP competitor gaps."),
1290
- includeCompetitors: z2.boolean().optional().describe("Whether to also merge recurring discovered competitor domains into the project. Defaults to true.")
1303
+ includeCompetitors: z2.boolean().optional().describe("Whether to also merge recurring discovered competitor domains into the project. Defaults to true."),
1304
+ competitorTypes: z2.array(discoveryCompetitorTypeSchema).min(1).optional().describe("Which classified competitor types to merge. Omitted promotes direct-competitor only; pass an explicit list to also adopt editorial-media channels or to recover legacy unknown entries. Ignored when includeCompetitors is false.")
1291
1305
  }).optional()
1292
1306
  });
1293
1307
  var AGENT_WEBHOOK_EVENTS = [
@@ -1876,6 +1890,17 @@ var canonryMcpTools = [
1876
1890
  openApiOperations: ["POST /api/v1/projects/{name}/traffic/connect/wordpress"],
1877
1891
  handler: (client, input) => client.trafficConnectWordpress(input.project, input.request)
1878
1892
  }),
1893
+ defineTool({
1894
+ name: "canonry_traffic_connect_vercel",
1895
+ title: "Connect Vercel traffic source",
1896
+ description: "Connect a Vercel project as a server-side traffic source. Pulls request logs from Vercel's internal request-logs endpoint \u2014 no in-app instrumentation needed. Probes the endpoint with the supplied API token before persisting \u2014 a bad token or wrong project / team id surfaces as a 502 error. Reconnecting updates the existing active Vercel source in place. The API token is stored in ~/.canonry/config.yaml (not the DB) and never echoed back.",
1897
+ access: "write",
1898
+ tier: "traffic",
1899
+ inputSchema: trafficConnectVercelInputSchema,
1900
+ annotations: writeAnnotations({ idempotentHint: true, openWorldHint: true }),
1901
+ openApiOperations: ["POST /api/v1/projects/{name}/traffic/connect/vercel"],
1902
+ handler: (client, input) => client.trafficConnectVercel(input.project, input.request)
1903
+ }),
1879
1904
  defineTool({
1880
1905
  name: "canonry_traffic_sync",
1881
1906
  title: "Sync Cloud Run traffic source",
@@ -2242,7 +2267,7 @@ var canonryMcpTools = [
2242
2267
  defineTool({
2243
2268
  name: "canonry_discover_promote",
2244
2269
  title: "Promote discovery session",
2245
- description: 'Adopt a completed discovery session\'s bucketed queries into the project\'s tracked basket, tagged with provenance "discovery:<sessionId>". By default, only cited + aspirational queries are promoted; include wasted-surface explicitly when off-ICP competitor gaps should also be tracked. Recurring discovered competitor domains are also merged by default. Add-only and idempotent: queries/domains already tracked are returned under `skipped`, never inserted twice. Only sessions with status "completed" can be promoted. Call canonry_discover_promote_preview first to inspect candidates.',
2270
+ description: 'Adopt a completed discovery session\'s bucketed queries into the project\'s tracked basket, tagged with provenance "discovery:<sessionId>". By default, only cited + aspirational queries are promoted; include wasted-surface explicitly when off-ICP competitor gaps should also be tracked. Recurring discovered competitor domains classified as direct-competitor are also merged by default \u2014 pass request.competitorTypes to adopt editorial-media channels or recover legacy unknown entries. Add-only and idempotent: queries/domains already tracked are returned under `skipped`, never inserted twice. Only sessions with status "completed" can be promoted. Call canonry_discover_promote_preview first to inspect candidates.',
2246
2271
  access: "write",
2247
2272
  tier: "discovery",
2248
2273
  inputSchema: discoveryPromoteInputSchema,
package/dist/cli.js CHANGED
@@ -20,7 +20,7 @@ import {
20
20
  setTelemetrySource,
21
21
  showFirstRunNotice,
22
22
  trackEvent
23
- } from "./chunk-PTFVEYUX.js";
23
+ } from "./chunk-7I65IXVU.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-NIAAHWRF.js";
39
+ } from "./chunk-LVX5TOYA.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-4EDC2P3J.js";
52
+ } from "./chunk-LUAJVZVZ.js";
53
53
  import {
54
54
  CcReleaseSyncStatuses,
55
55
  CheckScopes,
@@ -63,6 +63,7 @@ import {
63
63
  TrafficEventKinds,
64
64
  determineAnswerMentioned,
65
65
  discoveryBucketSchema,
66
+ discoveryCompetitorTypeSchema,
66
67
  effectiveDomains,
67
68
  formatRunErrorOneLine,
68
69
  normalizeUrlPath,
@@ -70,7 +71,7 @@ import {
70
71
  providerQuotaPolicySchema,
71
72
  resolveProviderInput,
72
73
  skillsClientSchema
73
- } from "./chunk-7UO3EGDB.js";
74
+ } from "./chunk-5M4PP6P4.js";
74
75
 
75
76
  // src/cli.ts
76
77
  import { pathToFileURL } from "url";
@@ -622,7 +623,7 @@ function readStoredGroundingSources(rawResponse) {
622
623
  return result;
623
624
  }
624
625
  async function backfillInsightsCommand(project, opts) {
625
- const { IntelligenceService } = await import("./intelligence-service-ASXADXLF.js");
626
+ const { IntelligenceService } = await import("./intelligence-service-RSRWDBHS.js");
626
627
  const config = loadConfig();
627
628
  const db = createClient(config.database);
628
629
  migrate(db);
@@ -2142,7 +2143,10 @@ async function discoverPromotePreview(project, sessionId, opts) {
2142
2143
  for (const q of preview.queriesByBucket.aspirational.slice(0, 10)) console.log(` + ${q}`);
2143
2144
  if (preview.suggestedCompetitors.length > 0) {
2144
2145
  console.log(` Suggested new competitors:`);
2145
- for (const c of preview.suggestedCompetitors) console.log(` - ${c.domain} (${c.hits} hits)`);
2146
+ for (const c of preview.suggestedCompetitors) {
2147
+ console.log(` - ${c.domain} (${c.hits} hits, ${c.competitorType})`);
2148
+ }
2149
+ console.log(" Only direct-competitor is promoted by default \u2014 pass --competitor-types to include other types.");
2146
2150
  }
2147
2151
  console.log(`
2148
2152
  Run \`canonry discover promote ${project} ${sessionId}\` to merge cited + aspirational queries.`);
@@ -2152,6 +2156,7 @@ async function discoverPromote(project, sessionId, opts) {
2152
2156
  const client = getClient4();
2153
2157
  const body = {};
2154
2158
  if (opts.buckets && opts.buckets.length > 0) body.buckets = opts.buckets;
2159
+ if (opts.competitorTypes && opts.competitorTypes.length > 0) body.competitorTypes = opts.competitorTypes;
2155
2160
  if (opts.includeCompetitors === false) body.includeCompetitors = false;
2156
2161
  const result = await client.promoteDiscovery(project, sessionId, body);
2157
2162
  if (opts.format === "json") {
@@ -2181,7 +2186,9 @@ function printSessionDetail(session) {
2181
2186
  console.log(` Buckets: cited=${session.citedCount ?? 0} wasted-surface=${session.wastedCount ?? 0} aspirational=${session.aspirationalCount ?? 0}`);
2182
2187
  if (session.competitorMap.length > 0) {
2183
2188
  console.log(` Top recurring competitor domains:`);
2184
- for (const c of session.competitorMap.slice(0, 10)) console.log(` - ${c.domain} (${c.hits} hits)`);
2189
+ for (const c of session.competitorMap.slice(0, 10)) {
2190
+ console.log(` - ${c.domain} (${c.hits} hits, ${c.competitorType})`);
2191
+ }
2185
2192
  }
2186
2193
  if (session.error) console.log(` Error: ${session.error}`);
2187
2194
  if (session.startedAt) console.log(` Started: ${session.startedAt}`);
@@ -2265,6 +2272,38 @@ Usage: ${usage}`,
2265
2272
  }
2266
2273
  return buckets;
2267
2274
  }
2275
+ var COMPETITOR_TYPE_VALUES = "direct-competitor, ota-aggregator, editorial-media, other, unknown";
2276
+ function parseCompetitorTypesOption(values, usage) {
2277
+ const raw = getStringArray(values, "competitor-types");
2278
+ if (!raw || raw.length === 0) return void 0;
2279
+ const expanded = raw.flatMap((v) => v.split(",")).map((v) => v.trim()).filter(Boolean);
2280
+ if (expanded.length === 0) {
2281
+ throw usageError(
2282
+ `Error: --competitor-types must include at least one value (valid: ${COMPETITOR_TYPE_VALUES})
2283
+ Usage: ${usage}`,
2284
+ {
2285
+ message: "--competitor-types must include at least one value",
2286
+ details: { command: "discover.promote", usage, option: "competitor-types", value: raw }
2287
+ }
2288
+ );
2289
+ }
2290
+ const types = [];
2291
+ for (const value of expanded) {
2292
+ const parsed = discoveryCompetitorTypeSchema.safeParse(value);
2293
+ if (!parsed.success) {
2294
+ throw usageError(
2295
+ `Error: invalid --competitor-types value "${value}" (valid: ${COMPETITOR_TYPE_VALUES})
2296
+ Usage: ${usage}`,
2297
+ {
2298
+ message: `invalid --competitor-types value "${value}"`,
2299
+ details: { command: "discover.promote", usage, option: "competitor-types", value }
2300
+ }
2301
+ );
2302
+ }
2303
+ types.push(parsed.data);
2304
+ }
2305
+ return types;
2306
+ }
2268
2307
  var DISCOVER_CLI_COMMANDS = [
2269
2308
  {
2270
2309
  path: ["discover", "run"],
@@ -2378,13 +2417,14 @@ var DISCOVER_CLI_COMMANDS = [
2378
2417
  },
2379
2418
  {
2380
2419
  path: ["discover", "promote"],
2381
- usage: "canonry discover promote <project> <session-id> [--bucket cited,aspirational,wasted-surface] [--no-competitors] [--format json]",
2420
+ usage: "canonry discover promote <project> <session-id> [--bucket cited,aspirational,wasted-surface] [--competitor-types direct-competitor,editorial-media] [--no-competitors] [--format json]",
2382
2421
  options: {
2383
2422
  bucket: multiStringOption(),
2423
+ "competitor-types": multiStringOption(),
2384
2424
  "no-competitors": { type: "boolean", default: false }
2385
2425
  },
2386
2426
  run: async (input) => {
2387
- const usage = "canonry discover promote <project> <session-id> [--bucket cited,aspirational,wasted-surface] [--no-competitors] [--format json]";
2427
+ const usage = "canonry discover promote <project> <session-id> [--bucket cited,aspirational,wasted-surface] [--competitor-types direct-competitor,editorial-media] [--no-competitors] [--format json]";
2388
2428
  const project = requireProject(input, "discover.promote", usage);
2389
2429
  const sessionId = requirePositional(input, 1, {
2390
2430
  command: "discover.promote",
@@ -2393,6 +2433,7 @@ var DISCOVER_CLI_COMMANDS = [
2393
2433
  });
2394
2434
  await discoverPromote(project, sessionId, {
2395
2435
  buckets: parseBucketsOption(input.values, usage),
2436
+ competitorTypes: parseCompetitorTypesOption(input.values, usage),
2396
2437
  includeCompetitors: !getBoolean(input.values, "no-competitors"),
2397
2438
  format: input.format
2398
2439
  });
@@ -3304,6 +3345,84 @@ async function trafficConnectCloudRun(project, opts) {
3304
3345
  console.log("");
3305
3346
  console.log(`Next: canonry traffic sync ${project} --source ${result.id}`);
3306
3347
  }
3348
+ async function trafficConnectVercel(project, opts) {
3349
+ if (!opts.projectId) {
3350
+ throw new CliError({
3351
+ code: "TRAFFIC_VERCEL_PROJECT_ID_REQUIRED",
3352
+ message: "--project-id is required",
3353
+ displayMessage: "Error: --project-id is required (the Vercel project id, e.g. prj_...)",
3354
+ details: { project }
3355
+ });
3356
+ }
3357
+ if (!opts.teamId) {
3358
+ throw new CliError({
3359
+ code: "TRAFFIC_VERCEL_TEAM_ID_REQUIRED",
3360
+ message: "--team-id is required",
3361
+ displayMessage: "Error: --team-id is required (the Vercel team / owner id, e.g. team_...)",
3362
+ details: { project }
3363
+ });
3364
+ }
3365
+ if (opts.token && opts.tokenFile) {
3366
+ throw new CliError({
3367
+ code: "TRAFFIC_VERCEL_TOKEN_CONFLICT",
3368
+ message: "--token and --token-file are mutually exclusive",
3369
+ displayMessage: "Error: pass either --token <token> or --token-file <path>, not both",
3370
+ details: { project }
3371
+ });
3372
+ }
3373
+ let token = opts.token?.trim() ?? "";
3374
+ if (!token && opts.tokenFile) {
3375
+ const fs13 = await import("fs");
3376
+ try {
3377
+ token = fs13.readFileSync(opts.tokenFile, "utf-8").trim();
3378
+ } catch (e) {
3379
+ const msg = e instanceof Error ? e.message : String(e);
3380
+ throw new CliError({
3381
+ code: "TRAFFIC_VERCEL_TOKEN_FILE_READ_ERROR",
3382
+ message: `Failed to read --token-file: ${msg}`,
3383
+ displayMessage: `Error: failed to read --token-file "${opts.tokenFile}": ${msg}`,
3384
+ details: { project, tokenFile: opts.tokenFile }
3385
+ });
3386
+ }
3387
+ }
3388
+ if (!token) {
3389
+ throw new CliError({
3390
+ code: "TRAFFIC_VERCEL_TOKEN_REQUIRED",
3391
+ message: "--token or --token-file is required",
3392
+ displayMessage: "Error: pass --token <token> or --token-file <path>",
3393
+ details: { project }
3394
+ });
3395
+ }
3396
+ if (opts.environment && opts.environment !== "production" && opts.environment !== "preview") {
3397
+ throw new CliError({
3398
+ code: "TRAFFIC_VERCEL_INVALID_ENVIRONMENT",
3399
+ message: '--environment must be "production" or "preview"',
3400
+ displayMessage: 'Error: --environment must be "production" or "preview"',
3401
+ details: { project, environment: opts.environment }
3402
+ });
3403
+ }
3404
+ const client = getClient6();
3405
+ const result = await client.trafficConnectVercel(project, {
3406
+ projectId: opts.projectId,
3407
+ teamId: opts.teamId,
3408
+ token,
3409
+ environment: opts.environment,
3410
+ displayName: opts.displayName
3411
+ });
3412
+ if (opts.format === "json") {
3413
+ console.log(JSON.stringify(result, null, 2));
3414
+ return;
3415
+ }
3416
+ console.log(`Vercel traffic source connected for project "${project}".`);
3417
+ console.log(` Source ID: ${result.id}`);
3418
+ console.log(` Display name: ${result.displayName}`);
3419
+ console.log(` Status: ${result.status}`);
3420
+ console.log(` Project ID: ${result.config.projectId ?? "(unset)"}`);
3421
+ console.log(` Team ID: ${result.config.teamId ?? "(unset)"}`);
3422
+ console.log(` Environment: ${result.config.environment ?? "(unset)"}`);
3423
+ console.log("");
3424
+ console.log(`Next: canonry traffic sync ${project} --source ${result.id}`);
3425
+ }
3307
3426
  async function trafficBackfill(project, opts) {
3308
3427
  if (!opts.source) {
3309
3428
  throw new CliError({
@@ -3585,6 +3704,38 @@ var TRAFFIC_CLI_COMMANDS = [
3585
3704
  });
3586
3705
  }
3587
3706
  },
3707
+ {
3708
+ path: ["traffic", "connect", "vercel"],
3709
+ usage: "canonry traffic connect vercel <project> --project-id <prj> --team-id <team> (--token <token> | --token-file <path>) [--environment production|preview] [--display-name <name>] [--format json]",
3710
+ options: {
3711
+ "project-id": stringOption(),
3712
+ "team-id": stringOption(),
3713
+ token: stringOption(),
3714
+ "token-file": stringOption(),
3715
+ environment: stringOption(),
3716
+ "display-name": stringOption()
3717
+ },
3718
+ run: async (input) => {
3719
+ const project = requireProject(
3720
+ input,
3721
+ "traffic.connect.vercel",
3722
+ "canonry traffic connect vercel <project> --project-id <prj> --team-id <team> (--token <token> | --token-file <path>)"
3723
+ );
3724
+ const projectId = getString(input.values, "project-id");
3725
+ if (!projectId) throw new Error("--project-id is required");
3726
+ const teamId = getString(input.values, "team-id");
3727
+ if (!teamId) throw new Error("--team-id is required");
3728
+ await trafficConnectVercel(project, {
3729
+ projectId,
3730
+ teamId,
3731
+ token: getString(input.values, "token"),
3732
+ tokenFile: getString(input.values, "token-file"),
3733
+ environment: getString(input.values, "environment"),
3734
+ displayName: getString(input.values, "display-name"),
3735
+ format: input.format
3736
+ });
3737
+ }
3738
+ },
3588
3739
  {
3589
3740
  path: ["traffic", "connect"],
3590
3741
  usage: "canonry traffic connect <provider> <project> [args]",
@@ -3592,7 +3743,7 @@ var TRAFFIC_CLI_COMMANDS = [
3592
3743
  unknownSubcommand(input.positionals[0], {
3593
3744
  command: "traffic connect",
3594
3745
  usage: "canonry traffic connect <provider> <project> [args]",
3595
- available: ["cloud-run", "wordpress"]
3746
+ available: ["cloud-run", "wordpress", "vercel"]
3596
3747
  });
3597
3748
  }
3598
3749
  },
@@ -11293,9 +11444,9 @@ var REGISTERED_CLI_COMMANDS = [
11293
11444
  // src/cli.ts
11294
11445
  import { createRequire as createRequire2 } from "module";
11295
11446
  var USAGE3 = `
11296
- canonry \u2014 AEO monitoring CLI
11447
+ cnry \u2014 AEO monitoring CLI ('canonry' also works)
11297
11448
 
11298
- Usage: canonry <command> [options]
11449
+ Usage: cnry <command> [options]
11299
11450
 
11300
11451
  Setup:
11301
11452
  init Initialize config and database
@@ -11343,7 +11494,7 @@ Global options:
11343
11494
  --help, -h Show help (use with any command group)
11344
11495
  --version, -v Show version
11345
11496
 
11346
- Run 'canonry <command> --help' for details on a specific command.
11497
+ Run 'cnry <command> --help' for details on a specific command.
11347
11498
  `.trim();
11348
11499
  var _require2 = createRequire2(import.meta.url);
11349
11500
  var { version: VERSION } = _require2("../package.json");
@@ -11394,11 +11545,11 @@ async function runCli(args = process.argv.slice(2)) {
11394
11545
  return 0;
11395
11546
  }
11396
11547
  throw usageError(`Error: unknown command: ${command}
11397
- Run "canonry --help" for usage.`, {
11548
+ Run "cnry --help" for usage.`, {
11398
11549
  message: `unknown command: ${command}`,
11399
11550
  details: {
11400
11551
  command,
11401
- usage: "canonry --help"
11552
+ usage: "cnry --help"
11402
11553
  }
11403
11554
  });
11404
11555
  } catch (err) {
package/dist/index.d.ts CHANGED
@@ -107,6 +107,25 @@ interface WordpressTrafficConnectionConfigEntry {
107
107
  interface WordpressTrafficConfigEntry {
108
108
  connections?: WordpressTrafficConnectionConfigEntry[];
109
109
  }
110
+ type VercelTrafficEnvironment = 'production' | 'preview';
111
+ /**
112
+ * Per-project Vercel traffic connection. Authenticates against Vercel's
113
+ * internal `request-logs` endpoint using a Vercel API token. The project id,
114
+ * team id, and environment are non-secret and also mirrored onto the
115
+ * `traffic_sources` row; the token lives only here.
116
+ */
117
+ interface VercelTrafficConnectionConfigEntry {
118
+ projectName: string;
119
+ projectId: string;
120
+ teamId: string;
121
+ token: string;
122
+ environment: VercelTrafficEnvironment;
123
+ createdAt: string;
124
+ updatedAt: string;
125
+ }
126
+ interface VercelTrafficConfigEntry {
127
+ connections?: VercelTrafficConnectionConfigEntry[];
128
+ }
110
129
  interface AgentConfigEntry {
111
130
  /** Agent mode. Only 'disabled' is valid until the native loop ships. */
112
131
  mode?: 'disabled';
@@ -130,6 +149,7 @@ interface CanonryConfig {
130
149
  cloudRun?: CloudRunConfigEntry;
131
150
  wordpress?: WordpressConfigEntry;
132
151
  wordpressTraffic?: WordpressTrafficConfigEntry;
152
+ vercelTraffic?: VercelTrafficConfigEntry;
133
153
  dashboardPasswordHash?: string;
134
154
  telemetry?: boolean;
135
155
  anonymousId?: string;
package/dist/index.js CHANGED
@@ -1,11 +1,11 @@
1
1
  import {
2
2
  createServer
3
- } from "./chunk-PTFVEYUX.js";
3
+ } from "./chunk-7I65IXVU.js";
4
4
  import {
5
5
  loadConfig
6
- } from "./chunk-NIAAHWRF.js";
7
- import "./chunk-4EDC2P3J.js";
8
- import "./chunk-7UO3EGDB.js";
6
+ } from "./chunk-LVX5TOYA.js";
7
+ import "./chunk-LUAJVZVZ.js";
8
+ import "./chunk-5M4PP6P4.js";
9
9
  export {
10
10
  createServer,
11
11
  loadConfig
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  IntelligenceService
3
- } from "./chunk-4EDC2P3J.js";
4
- import "./chunk-7UO3EGDB.js";
3
+ } from "./chunk-LUAJVZVZ.js";
4
+ import "./chunk-5M4PP6P4.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-NIAAHWRF.js";
6
- import "./chunk-7UO3EGDB.js";
5
+ } from "./chunk-LVX5TOYA.js";
6
+ import "./chunk-5M4PP6P4.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.30.0",
3
+ "version": "4.32.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",
@@ -15,6 +15,7 @@
15
15
  },
16
16
  "bin": {
17
17
  "canonry": "./bin/canonry.mjs",
18
+ "cnry": "./bin/canonry.mjs",
18
19
  "canonry-mcp": "./bin/canonry-mcp.mjs"
19
20
  },
20
21
  "exports": {
@@ -59,23 +60,23 @@
59
60
  "@types/node-cron": "^3.0.11",
60
61
  "tsup": "^8.5.1",
61
62
  "tsx": "^4.19.0",
62
- "@ainyc/canonry-api-routes": "0.0.0",
63
63
  "@ainyc/canonry-config": "0.0.0",
64
- "@ainyc/canonry-contracts": "0.0.0",
64
+ "@ainyc/canonry-api-routes": "0.0.0",
65
65
  "@ainyc/canonry-db": "0.0.0",
66
66
  "@ainyc/canonry-integration-bing": "0.0.0",
67
67
  "@ainyc/canonry-intelligence": "0.0.0",
68
+ "@ainyc/canonry-integration-cloud-run": "0.0.0",
68
69
  "@ainyc/canonry-integration-commoncrawl": "0.0.0",
69
70
  "@ainyc/canonry-integration-google": "0.0.0",
70
71
  "@ainyc/canonry-integration-traffic": "0.0.0",
71
- "@ainyc/canonry-integration-cloud-run": "0.0.0",
72
72
  "@ainyc/canonry-integration-wordpress": "0.0.0",
73
- "@ainyc/canonry-provider-claude": "0.0.0",
73
+ "@ainyc/canonry-contracts": "0.0.0",
74
74
  "@ainyc/canonry-provider-cdp": "0.0.0",
75
+ "@ainyc/canonry-provider-gemini": "0.0.0",
75
76
  "@ainyc/canonry-provider-local": "0.0.0",
77
+ "@ainyc/canonry-provider-claude": "0.0.0",
76
78
  "@ainyc/canonry-provider-openai": "0.0.0",
77
- "@ainyc/canonry-provider-perplexity": "0.0.0",
78
- "@ainyc/canonry-provider-gemini": "0.0.0"
79
+ "@ainyc/canonry-provider-perplexity": "0.0.0"
79
80
  },
80
81
  "scripts": {
81
82
  "build": "tsx scripts/copy-agent-assets.ts && tsup && tsx build-web.ts",