@ainyc/canonry 4.21.4 → 4.23.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -2227,6 +2227,10 @@ var cloudRunSourceConfigSchema = z20.object({
2227
2227
  location: z20.string().nullable().optional(),
2228
2228
  authMode: trafficSourceAuthModeSchema
2229
2229
  });
2230
+ var wordpressTrafficSourceConfigSchema = z20.object({
2231
+ baseUrl: z20.string().url(),
2232
+ username: z20.string().min(1)
2233
+ });
2230
2234
  var trafficSourceDtoSchema = z20.object({
2231
2235
  id: z20.string(),
2232
2236
  projectId: z20.string(),
@@ -2249,6 +2253,13 @@ var trafficConnectCloudRunRequestSchema = z20.object({
2249
2253
  /** Service-account JSON content (string). When omitted, defaults to OAuth via `canonry google connect <project> --type ga4` flow. */
2250
2254
  keyJson: z20.string().optional()
2251
2255
  });
2256
+ var trafficConnectWordpressRequestSchema = z20.object({
2257
+ baseUrl: z20.string().url(),
2258
+ username: z20.string().min(1),
2259
+ /** WordPress Application Password (the same auth used by the content client). */
2260
+ applicationPassword: z20.string().min(1),
2261
+ displayName: z20.string().min(1).optional()
2262
+ });
2252
2263
  var trafficSyncResponseSchema = z20.object({
2253
2264
  sourceId: z20.string(),
2254
2265
  runId: z20.string(),
@@ -2494,6 +2505,7 @@ export {
2494
2505
  TrafficSourceAuthModes,
2495
2506
  VerificationStatuses,
2496
2507
  trafficConnectCloudRunRequestSchema,
2508
+ trafficConnectWordpressRequestSchema,
2497
2509
  trafficEventKindSchema,
2498
2510
  TrafficEventKinds,
2499
2511
  formatRatio,
@@ -8,7 +8,7 @@ import {
8
8
  categoryLabel,
9
9
  determineAnswerMentioned,
10
10
  normalizeProjectDomain
11
- } from "./chunk-EY63PENL.js";
11
+ } from "./chunk-EUGCQSFC.js";
12
12
 
13
13
  // src/intelligence-service.ts
14
14
  import { eq, desc, asc, and, or, inArray } from "drizzle-orm";
package/dist/cli.js CHANGED
@@ -20,7 +20,7 @@ import {
20
20
  setTelemetrySource,
21
21
  showFirstRunNotice,
22
22
  trackEvent
23
- } from "./chunk-3UGJUNQX.js";
23
+ } from "./chunk-E5PZ23OS.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-VFKGHXVJ.js";
39
+ } from "./chunk-6EJ54OX7.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-GVQYROIK.js";
52
+ } from "./chunk-OYYFXKRK.js";
53
53
  import {
54
54
  CcReleaseSyncStatuses,
55
55
  CheckScopes,
@@ -69,7 +69,7 @@ import {
69
69
  providerQuotaPolicySchema,
70
70
  resolveProviderInput,
71
71
  skillsClientSchema
72
- } from "./chunk-EY63PENL.js";
72
+ } from "./chunk-EUGCQSFC.js";
73
73
 
74
74
  // src/cli.ts
75
75
  import { pathToFileURL } from "url";
@@ -621,7 +621,7 @@ function readStoredGroundingSources(rawResponse) {
621
621
  return result;
622
622
  }
623
623
  async function backfillInsightsCommand(project, opts) {
624
- const { IntelligenceService } = await import("./intelligence-service-5COCQKXG.js");
624
+ const { IntelligenceService } = await import("./intelligence-service-NVN2PAR7.js");
625
625
  const config = loadConfig();
626
626
  const db = createClient(config.database);
627
627
  migrate(db);
@@ -2722,6 +2722,74 @@ var GA_CLI_COMMANDS = [
2722
2722
  function getClient5() {
2723
2723
  return createApiClient();
2724
2724
  }
2725
+ async function trafficConnectWordpress(project, opts) {
2726
+ if (!opts.url) {
2727
+ throw new CliError({
2728
+ code: "TRAFFIC_WP_URL_REQUIRED",
2729
+ message: "--url is required",
2730
+ displayMessage: "Error: --url is required",
2731
+ details: { project }
2732
+ });
2733
+ }
2734
+ if (!opts.username) {
2735
+ throw new CliError({
2736
+ code: "TRAFFIC_WP_USERNAME_REQUIRED",
2737
+ message: "--username is required",
2738
+ displayMessage: "Error: --username is required",
2739
+ details: { project }
2740
+ });
2741
+ }
2742
+ if (opts.appPassword && opts.appPasswordFile) {
2743
+ throw new CliError({
2744
+ code: "TRAFFIC_WP_APP_PASSWORD_CONFLICT",
2745
+ message: "--app-password and --app-password-file are mutually exclusive",
2746
+ displayMessage: "Error: pass either --app-password <pw> or --app-password-file <path>, not both",
2747
+ details: { project }
2748
+ });
2749
+ }
2750
+ let applicationPassword = opts.appPassword?.trim() ?? "";
2751
+ if (!applicationPassword && opts.appPasswordFile) {
2752
+ const fs13 = await import("fs");
2753
+ try {
2754
+ applicationPassword = fs13.readFileSync(opts.appPasswordFile, "utf-8").trim();
2755
+ } catch (e) {
2756
+ const msg = e instanceof Error ? e.message : String(e);
2757
+ throw new CliError({
2758
+ code: "TRAFFIC_WP_APP_PASSWORD_FILE_READ_ERROR",
2759
+ message: `Failed to read --app-password-file: ${msg}`,
2760
+ displayMessage: `Error: failed to read --app-password-file "${opts.appPasswordFile}": ${msg}`,
2761
+ details: { project, appPasswordFile: opts.appPasswordFile }
2762
+ });
2763
+ }
2764
+ }
2765
+ if (!applicationPassword) {
2766
+ throw new CliError({
2767
+ code: "TRAFFIC_WP_APP_PASSWORD_REQUIRED",
2768
+ message: "--app-password or --app-password-file is required",
2769
+ displayMessage: "Error: pass --app-password <pw> or --app-password-file <path>",
2770
+ details: { project }
2771
+ });
2772
+ }
2773
+ const client = getClient5();
2774
+ const result = await client.trafficConnectWordpress(project, {
2775
+ baseUrl: opts.url,
2776
+ username: opts.username,
2777
+ applicationPassword,
2778
+ displayName: opts.displayName
2779
+ });
2780
+ if (opts.format === "json") {
2781
+ console.log(JSON.stringify(result, null, 2));
2782
+ return;
2783
+ }
2784
+ console.log(`WordPress traffic source connected for project "${project}".`);
2785
+ console.log(` Source ID: ${result.id}`);
2786
+ console.log(` Display name: ${result.displayName}`);
2787
+ console.log(` Status: ${result.status}`);
2788
+ console.log(` Site URL: ${result.config.baseUrl ?? "(unset)"}`);
2789
+ console.log(` Username: ${result.config.username ?? "(unset)"}`);
2790
+ console.log("");
2791
+ console.log(`Next: canonry traffic sync ${project} --source ${result.id}`);
2792
+ }
2725
2793
  async function trafficConnectCloudRun(project, opts) {
2726
2794
  if (!opts.gcpProject) {
2727
2795
  throw new CliError({
@@ -2919,7 +2987,7 @@ async function trafficStatus(project, opts) {
2919
2987
  console.log(` Last synced: ${d.lastSyncedAt ?? "never"}`);
2920
2988
  if (d.lastError) console.log(` Last error: ${d.lastError}`);
2921
2989
  console.log(` 24h crawler: ${d.totals24h.crawlerHits} hits`);
2922
- console.log(` 24h AI referral: ${d.totals24h.aiReferralHits} hits`);
2990
+ console.log(` 24h AI referral: ${d.totals24h.aiReferralHits} sessions`);
2923
2991
  console.log(` 24h samples: ${d.totals24h.sampleCount}`);
2924
2992
  if (d.latestRun) {
2925
2993
  console.log(` Latest run: ${d.latestRun.runId} (${d.latestRun.status})`);
@@ -2982,13 +3050,13 @@ async function trafficEvents(project, opts) {
2982
3050
  }
2983
3051
  console.log(`Traffic events for "${project}" ${result.windowStart} \u2192 ${result.windowEnd}`);
2984
3052
  console.log(` Crawler hits (window): ${result.totals.crawlerHits}`);
2985
- console.log(` AI referral hits (window): ${result.totals.aiReferralHits}`);
3053
+ console.log(` AI referral sessions (window): ${result.totals.aiReferralHits}`);
2986
3054
  console.log("");
2987
3055
  if (result.events.length === 0) {
2988
3056
  console.log("No events in this window.");
2989
3057
  return;
2990
3058
  }
2991
- console.log(" TS_HOUR KIND IDENTITY EVIDENCE/STATUS PATH HITS");
3059
+ console.log(" TS_HOUR KIND IDENTITY EVIDENCE/STATUS PATH COUNT");
2992
3060
  for (const event of result.events) {
2993
3061
  console.log(` ${formatEventLine(event)}`);
2994
3062
  }
@@ -3026,6 +3094,36 @@ var TRAFFIC_CLI_COMMANDS = [
3026
3094
  });
3027
3095
  }
3028
3096
  },
3097
+ {
3098
+ path: ["traffic", "connect", "wordpress"],
3099
+ usage: "canonry traffic connect wordpress <project> --url <wp-site-url> --username <wp-user> (--app-password <pw> | --app-password-file <path>) [--display-name <name>] [--format json]",
3100
+ options: {
3101
+ url: stringOption(),
3102
+ username: stringOption(),
3103
+ "app-password": stringOption(),
3104
+ "app-password-file": stringOption(),
3105
+ "display-name": stringOption()
3106
+ },
3107
+ run: async (input) => {
3108
+ const project = requireProject(
3109
+ input,
3110
+ "traffic.connect.wordpress",
3111
+ "canonry traffic connect wordpress <project> --url <wp-site-url> --username <wp-user> (--app-password <pw> | --app-password-file <path>)"
3112
+ );
3113
+ const url = getString(input.values, "url");
3114
+ if (!url) throw new Error("--url is required");
3115
+ const username = getString(input.values, "username");
3116
+ if (!username) throw new Error("--username is required");
3117
+ await trafficConnectWordpress(project, {
3118
+ url,
3119
+ username,
3120
+ appPassword: getString(input.values, "app-password"),
3121
+ appPasswordFile: getString(input.values, "app-password-file"),
3122
+ displayName: getString(input.values, "display-name"),
3123
+ format: input.format
3124
+ });
3125
+ }
3126
+ },
3029
3127
  {
3030
3128
  path: ["traffic", "connect"],
3031
3129
  usage: "canonry traffic connect <provider> <project> [args]",
@@ -3033,7 +3131,7 @@ var TRAFFIC_CLI_COMMANDS = [
3033
3131
  unknownSubcommand(input.positionals[0], {
3034
3132
  command: "traffic connect",
3035
3133
  usage: "canonry traffic connect <provider> <project> [args]",
3036
- available: ["cloud-run"]
3134
+ available: ["cloud-run", "wordpress"]
3037
3135
  });
3038
3136
  }
3039
3137
  },
package/dist/index.d.ts CHANGED
@@ -91,6 +91,22 @@ interface WordpressConnectionConfigEntry {
91
91
  interface WordpressConfigEntry {
92
92
  connections?: WordpressConnectionConfigEntry[];
93
93
  }
94
+ /**
95
+ * Per-project WordPress traffic-logger connection. Separate from `wordpress.connections`,
96
+ * which is the content-publishing client. Authenticates against the WP traffic plugin's
97
+ * REST endpoint using a WordPress Application Password.
98
+ */
99
+ interface WordpressTrafficConnectionConfigEntry {
100
+ projectName: string;
101
+ baseUrl: string;
102
+ username: string;
103
+ applicationPassword: string;
104
+ createdAt: string;
105
+ updatedAt: string;
106
+ }
107
+ interface WordpressTrafficConfigEntry {
108
+ connections?: WordpressTrafficConnectionConfigEntry[];
109
+ }
94
110
  interface AgentConfigEntry {
95
111
  /** Agent mode. Only 'disabled' is valid until the native loop ships. */
96
112
  mode?: 'disabled';
@@ -113,6 +129,7 @@ interface CanonryConfig {
113
129
  ga4?: Ga4ConfigEntry;
114
130
  cloudRun?: CloudRunConfigEntry;
115
131
  wordpress?: WordpressConfigEntry;
132
+ wordpressTraffic?: WordpressTrafficConfigEntry;
116
133
  dashboardPasswordHash?: string;
117
134
  telemetry?: boolean;
118
135
  anonymousId?: string;
package/dist/index.js CHANGED
@@ -1,11 +1,11 @@
1
1
  import {
2
2
  createServer
3
- } from "./chunk-3UGJUNQX.js";
3
+ } from "./chunk-E5PZ23OS.js";
4
4
  import {
5
5
  loadConfig
6
- } from "./chunk-VFKGHXVJ.js";
7
- import "./chunk-GVQYROIK.js";
8
- import "./chunk-EY63PENL.js";
6
+ } from "./chunk-6EJ54OX7.js";
7
+ import "./chunk-OYYFXKRK.js";
8
+ import "./chunk-EUGCQSFC.js";
9
9
  export {
10
10
  createServer,
11
11
  loadConfig
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  IntelligenceService
3
- } from "./chunk-GVQYROIK.js";
4
- import "./chunk-EY63PENL.js";
3
+ } from "./chunk-OYYFXKRK.js";
4
+ import "./chunk-EUGCQSFC.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-VFKGHXVJ.js";
6
- import "./chunk-EY63PENL.js";
5
+ } from "./chunk-6EJ54OX7.js";
6
+ import "./chunk-EUGCQSFC.js";
7
7
 
8
8
  // src/mcp/cli.ts
9
9
  import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
@@ -137,7 +137,7 @@ var CANONRY_MCP_TOOLKITS = [
137
137
  name: "traffic",
138
138
  title: "Server-side traffic ingestion",
139
139
  description: "Connect Cloud Run traffic sources, trigger syncs, and read crawler / AI-referral hourly rollups straight from server logs (no GA dependency).",
140
- whenToLoad: "Load when you need server-log evidence of crawler hits or AI-referral arrivals (e.g. confirming GPTBot or ChatGPT-User on a page), or when wiring up / syncing a Cloud Run traffic source."
140
+ whenToLoad: "Load when you need server-log evidence of crawler hits or AI-referral sessions (e.g. confirming GPTBot or ChatGPT-User on a page), or when wiring up / syncing a Cloud Run traffic source."
141
141
  },
142
142
  {
143
143
  name: "agent",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ainyc/canonry",
3
- "version": "4.21.4",
3
+ "version": "4.23.1",
4
4
  "type": "module",
5
5
  "description": "Agent-first open-source AEO operating platform - track how answer engines cite your domain",
6
6
  "license": "FSL-1.1-ALv2",
@@ -60,22 +60,22 @@
60
60
  "tsup": "^8.5.1",
61
61
  "tsx": "^4.19.0",
62
62
  "@ainyc/canonry-api-routes": "0.0.0",
63
- "@ainyc/canonry-config": "0.0.0",
63
+ "@ainyc/canonry-contracts": "0.0.0",
64
64
  "@ainyc/canonry-db": "0.0.0",
65
- "@ainyc/canonry-integration-bing": "0.0.0",
65
+ "@ainyc/canonry-config": "0.0.0",
66
66
  "@ainyc/canonry-intelligence": "0.0.0",
67
+ "@ainyc/canonry-integration-bing": "0.0.0",
67
68
  "@ainyc/canonry-integration-commoncrawl": "0.0.0",
68
- "@ainyc/canonry-integration-cloud-run": "0.0.0",
69
69
  "@ainyc/canonry-integration-google": "0.0.0",
70
- "@ainyc/canonry-contracts": "0.0.0",
71
- "@ainyc/canonry-integration-traffic": "0.0.0",
70
+ "@ainyc/canonry-integration-cloud-run": "0.0.0",
72
71
  "@ainyc/canonry-integration-wordpress": "0.0.0",
72
+ "@ainyc/canonry-provider-cdp": "0.0.0",
73
+ "@ainyc/canonry-integration-traffic": "0.0.0",
73
74
  "@ainyc/canonry-provider-claude": "0.0.0",
74
- "@ainyc/canonry-provider-gemini": "0.0.0",
75
- "@ainyc/canonry-provider-openai": "0.0.0",
76
75
  "@ainyc/canonry-provider-local": "0.0.0",
77
- "@ainyc/canonry-provider-perplexity": "0.0.0",
78
- "@ainyc/canonry-provider-cdp": "0.0.0"
76
+ "@ainyc/canonry-provider-openai": "0.0.0",
77
+ "@ainyc/canonry-provider-gemini": "0.0.0",
78
+ "@ainyc/canonry-provider-perplexity": "0.0.0"
79
79
  },
80
80
  "scripts": {
81
81
  "build": "tsx scripts/copy-agent-assets.ts && tsup && tsx build-web.ts",