@canonry/canonry 5.21.0 → 5.28.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.
Files changed (43) hide show
  1. package/README.md +2 -1
  2. package/assets/agent-workspace/skills/aero/SKILL.md +37 -3
  3. package/assets/agent-workspace/skills/aero/references/portfolio-analysis.md +26 -12
  4. package/assets/agent-workspace/skills/aero/references/reporting.md +1 -0
  5. package/assets/agent-workspace/skills/canonry/references/canonry-cli.md +101 -6
  6. package/assets/agent-workspace/skills/canonry/references/google-business-profile.md +30 -6
  7. package/assets/agent-workspace/skills/canonry/references/indexing.md +1 -0
  8. package/assets/agent-workspace/skills/canonry/references/server-side-traffic.md +30 -0
  9. package/assets/assets/{AuditHistoryPanel-CjxWA3lx.js → AuditHistoryPanel-CWd9UN6L.js} +1 -1
  10. package/assets/assets/{BacklinksPage-Bdd164Up.js → BacklinksPage-B2gPTzyE.js} +1 -1
  11. package/assets/assets/ChartPrimitives-B5okB5g-.js +1 -0
  12. package/assets/assets/{HistoryPage-BvJmE-kP.js → HistoryPage-xtkG8SZN.js} +1 -1
  13. package/assets/assets/{MeasurementPropertyPage-HuP6RMZ-.js → MeasurementPropertyPage-DxIMU3_T.js} +1 -1
  14. package/assets/assets/{ProjectPage-DOvXVbyy.js → ProjectPage-CMAFZq_s.js} +5 -5
  15. package/assets/assets/{RunRow-Cnb3JOBw.js → RunRow-DnSo7Nle.js} +1 -1
  16. package/assets/assets/{RunsPage-Dvz1JYIm.js → RunsPage-FAEuo4Ra.js} +1 -1
  17. package/assets/assets/{SettingsPage-DYGvphkg.js → SettingsPage-C4OZ1HB9.js} +1 -1
  18. package/assets/assets/{SiteHealthSection-CUNiKaod.js → SiteHealthSection-BzMxlz8-.js} +3 -3
  19. package/assets/assets/{TrafficPage-Bf4Tq95q.js → TrafficPage-D03S6xF6.js} +1 -1
  20. package/assets/assets/{TrafficSourceDetailPage-CIuLWZgT.js → TrafficSourceDetailPage-DBu6oFFK.js} +1 -1
  21. package/assets/assets/{extract-error-message-DZex1e4H.js → extract-error-message-BuH2CCaJ.js} +1 -1
  22. package/assets/assets/index-Ba-Zs45G.js +86 -0
  23. package/assets/assets/index-DfhmHULl.css +1 -0
  24. package/assets/assets/{react-sigma_core.esm.min-CxvtwEkv.js → react-sigma_core.esm.min-CxwZsgxR.js} +1 -1
  25. package/assets/assets/{v2-overview-adapter-Bh4qIzLp.js → v2-overview-adapter-DTCKxzZT.js} +1 -1
  26. package/assets/index.html +2 -2
  27. package/dist/{chunk-FAVYLZQV.js → chunk-7RKCDOWO.js} +7005 -5086
  28. package/dist/{chunk-MEAKE5W7.js → chunk-DX2JUC5H.js} +3 -3
  29. package/dist/{chunk-NFN5GSEJ.js → chunk-EP4STEPI.js} +3558 -1170
  30. package/dist/{chunk-FRWZWJB3.js → chunk-FNGITGDF.js} +176 -8
  31. package/dist/{chunk-2LO7FLVD.js → chunk-KVQHG3WB.js} +6721 -5889
  32. package/dist/{chunk-WUT3G2GM.js → chunk-MPICT6V7.js} +131 -36
  33. package/dist/{chunk-HDJHQPW3.js → chunk-ONTEFAA7.js} +2 -2
  34. package/dist/cli.js +443 -48
  35. package/dist/{demo-server-7BVVVXPM.js → demo-server-HWWIMGD6.js} +4 -4
  36. package/dist/index.d.ts +9 -1
  37. package/dist/index.js +6 -6
  38. package/dist/{intelligence-service-3UUKRAZ5.js → intelligence-service-6LDMVI66.js} +2 -2
  39. package/dist/mcp.js +4 -4
  40. package/package.json +12 -11
  41. package/assets/assets/ChartPrimitives-BQC2VH0O.js +0 -1
  42. package/assets/assets/index-CeXW-lzj.js +0 -86
  43. package/assets/assets/index-EJC8PSbh.css +0 -1
@@ -5,12 +5,14 @@ import {
5
5
  PACKAGE_VERSION,
6
6
  canonryMcpTools,
7
7
  isMachineFormat
8
- } from "./chunk-WUT3G2GM.js";
8
+ } from "./chunk-MPICT6V7.js";
9
9
  import {
10
10
  AGENT_PROVIDER_IDS,
11
11
  CANONRY_NPM_PACKAGE_URL,
12
12
  CodingAgents,
13
13
  DEFAULT_VIEWER_RESEARCH_DAILY_RUN_LIMIT,
14
+ OPERATIONAL_LOG_FIELDS_HEADER,
15
+ OPERATIONAL_LOG_OPT_IN_CONTEXT_FIELDS,
14
16
  RESEARCH_RUN_SCOPE,
15
17
  SKILL_MANIFEST_FILENAME,
16
18
  SkillsClients,
@@ -30,6 +32,9 @@ import {
30
32
  isStrictSemver,
31
33
  normalizeAgentSlug,
32
34
  normalizeTelemetryStatus,
35
+ operationalLogListReadSchema,
36
+ providerBatchConfigSchema,
37
+ providerPricingSchema,
33
38
  providerQuotaPolicySchema,
34
39
  resolveProviderModel,
35
40
  restrictedWriteScopes,
@@ -37,7 +42,7 @@ import {
37
42
  skillsClientSchema,
38
43
  upgradeCaveatFor,
39
44
  upgradeCommandFor
40
- } from "./chunk-2LO7FLVD.js";
45
+ } from "./chunk-KVQHG3WB.js";
41
46
 
42
47
  // src/config.ts
43
48
  import fs from "fs";
@@ -99,6 +104,13 @@ var envSchema = z.object({
99
104
  PERPLEXITY_MAX_CONCURRENCY: z.coerce.number().int().positive().default(2),
100
105
  PERPLEXITY_MAX_REQUESTS_PER_MINUTE: z.coerce.number().int().positive().default(10),
101
106
  PERPLEXITY_MAX_REQUESTS_PER_DAY: z.coerce.number().int().positive().default(1e3),
107
+ // Meta Muse
108
+ MUSE_API_KEY: z.string().optional(),
109
+ MUSE_MODEL: z.string().optional(),
110
+ MUSE_BASE_URL: z.string().optional(),
111
+ MUSE_MAX_CONCURRENCY: z.coerce.number().int().positive().default(2),
112
+ MUSE_MAX_REQUESTS_PER_MINUTE: z.coerce.number().int().positive().default(10),
113
+ MUSE_MAX_REQUESTS_PER_DAY: z.coerce.number().int().positive().default(1e3),
102
114
  // Secret for HMAC-signing Google OAuth state parameters. Required for
103
115
  // cloud deployments that mount googleRoutes; the plugin refuses to register
104
116
  // without it (see packages/api-routes/src/google.ts).
@@ -123,6 +135,9 @@ var bootstrapEnvSchema = z.object({
123
135
  ANTHROPIC_MODEL: z.string().optional(),
124
136
  PERPLEXITY_API_KEY: z.string().optional(),
125
137
  PERPLEXITY_MODEL: z.string().optional(),
138
+ MUSE_API_KEY: z.string().optional(),
139
+ MUSE_MODEL: z.string().optional(),
140
+ MUSE_BASE_URL: z.string().optional(),
126
141
  LOCAL_BASE_URL: z.string().optional(),
127
142
  LOCAL_API_KEY: z.string().optional(),
128
143
  LOCAL_MODEL: z.string().optional(),
@@ -182,6 +197,19 @@ function getBootstrapEnv(source, overrides) {
182
197
  })
183
198
  };
184
199
  }
200
+ const museKey = parsed.MUSE_API_KEY?.trim();
201
+ if (museKey) {
202
+ providers.muse = {
203
+ apiKey: museKey,
204
+ model: parsed.MUSE_MODEL?.trim() || "muse-spark-1.3",
205
+ baseUrl: parsed.MUSE_BASE_URL?.trim() || void 0,
206
+ quota: providerQuotaPolicySchema.parse({
207
+ maxConcurrency: 2,
208
+ maxRequestsPerMinute: 10,
209
+ maxRequestsPerDay: 500
210
+ })
211
+ };
212
+ }
185
213
  if (parsed.LOCAL_BASE_URL) {
186
214
  providers.local = {
187
215
  baseUrl: parsed.LOCAL_BASE_URL,
@@ -204,6 +232,63 @@ function getBootstrapEnv(source, overrides) {
204
232
  };
205
233
  }
206
234
 
235
+ // src/provider-batch-config.ts
236
+ function issuesText(issues) {
237
+ return issues.map((issue) => issue.path.length ? `${issue.path.join(".")}: ${issue.message}` : issue.message).join("; ");
238
+ }
239
+ function normalizeProviderBatchSettings(providers, configPath) {
240
+ for (const [name, entry] of Object.entries(providers ?? {})) {
241
+ if (!entry) continue;
242
+ if (entry.batch !== void 0) {
243
+ const parsed = providerBatchConfigSchema.safeParse(entry.batch);
244
+ if (!parsed.success) {
245
+ throw new CliError({
246
+ code: "CONFIG_INVALID",
247
+ message: `Invalid config at ${configPath}: providers.${name}.batch is invalid (${issuesText(parsed.error.issues)}). Allowed keys: enabled (true/false), maxRequestsPerBatch (positive integer), deadlineHours (positive number).`
248
+ });
249
+ }
250
+ entry.batch = parsed.data;
251
+ }
252
+ if (entry.pricing !== void 0) {
253
+ const parsed = providerPricingSchema.safeParse(entry.pricing);
254
+ if (!parsed.success) {
255
+ throw new CliError({
256
+ code: "CONFIG_INVALID",
257
+ message: `Invalid config at ${configPath}: providers.${name}.pricing is invalid (${issuesText(parsed.error.issues)}). Prices are USD: inputPerMTok / cachedInputPerMTok / cacheWritePerMTok / outputPerMTok per million tokens, searchPer1k per 1,000 searches.`
258
+ });
259
+ }
260
+ entry.pricing = parsed.data;
261
+ }
262
+ }
263
+ }
264
+ function providerConfigFromEntry(name, entry, quotaPolicy) {
265
+ return {
266
+ provider: name,
267
+ apiKey: entry.apiKey,
268
+ baseUrl: entry.baseUrl,
269
+ model: entry.model,
270
+ quotaPolicy,
271
+ vertexProject: entry.vertexProject,
272
+ vertexRegion: entry.vertexRegion,
273
+ vertexCredentials: entry.vertexCredentials,
274
+ ...entry.batch ? { batch: entry.batch } : {},
275
+ ...entry.pricing ? { pricing: entry.pricing } : {}
276
+ };
277
+ }
278
+ function adapterSupportsBatch(adapter) {
279
+ return adapter.batch !== void 0 && adapter.buildTrackedQueryRequest !== void 0 && adapter.parseTrackedQueryResponse !== void 0;
280
+ }
281
+ function batchEligibleProviderNames(registry) {
282
+ return registry.getAll().filter((provider) => provider.config.batch?.enabled === true && adapterSupportsBatch(provider.adapter)).map((provider) => provider.adapter.name).sort();
283
+ }
284
+ function providersWithUnsupportedBatch(providers, adapterFor) {
285
+ return Object.entries(providers ?? {}).filter(([name, entry]) => {
286
+ if (entry?.batch?.enabled !== true) return false;
287
+ const adapter = adapterFor(name);
288
+ return adapter !== void 0 && !adapterSupportsBatch(adapter);
289
+ }).map(([name]) => name).sort();
290
+ }
291
+
207
292
  // src/config.ts
208
293
  function normalizeGoogleConfig(config) {
209
294
  if (!config.google) return;
@@ -343,6 +428,7 @@ Do not use "canonry init --force" for recovery. It replaces credentials without
343
428
  }
344
429
  };
345
430
  }
431
+ normalizeProviderBatchSettings(parsed.providers, configPath);
346
432
  normalizeGoogleConfig(parsed);
347
433
  normalizeGoogleMarketingConfig(parsed);
348
434
  normalizeWordpressConfig(parsed);
@@ -3655,6 +3741,18 @@ var getApiV1ProjectsByNameGoogleGscTopPages = (options) => {
3655
3741
  ...options
3656
3742
  });
3657
3743
  };
3744
+ var getApiV1ProjectsByNameGoogleGscQueryTotals = (options) => {
3745
+ return (options.client ?? client).get({
3746
+ security: [
3747
+ {
3748
+ scheme: "bearer",
3749
+ type: "http"
3750
+ }
3751
+ ],
3752
+ url: "/api/v1/projects/{name}/google/gsc/query-totals",
3753
+ ...options
3754
+ });
3755
+ };
3658
3756
  var postApiV1ProjectsByNameGoogleGscInspect = (options) => {
3659
3757
  return (options.client ?? client).post({
3660
3758
  security: [
@@ -3931,6 +4029,18 @@ var getApiV1ProjectsByNameGbpPlaces = (options) => {
3931
4029
  ...options
3932
4030
  });
3933
4031
  };
4032
+ var getApiV1ProjectsByNameGbpReviews = (options) => {
4033
+ return (options.client ?? client).get({
4034
+ security: [
4035
+ {
4036
+ scheme: "bearer",
4037
+ type: "http"
4038
+ }
4039
+ ],
4040
+ url: "/api/v1/projects/{name}/gbp/reviews",
4041
+ ...options
4042
+ });
4043
+ };
3934
4044
  var getApiV1ProjectsByNameGbpSummary = (options) => {
3935
4045
  return (options.client ?? client).get({
3936
4046
  security: [
@@ -5515,6 +5625,18 @@ var getApiV1ProjectsByNameTrafficSourcesById = (options) => {
5515
5625
  ...options
5516
5626
  });
5517
5627
  };
5628
+ var getApiV1ProjectsByNameTrafficReferralAssessment = (options) => {
5629
+ return (options.client ?? client).get({
5630
+ security: [
5631
+ {
5632
+ scheme: "bearer",
5633
+ type: "http"
5634
+ }
5635
+ ],
5636
+ url: "/api/v1/projects/{name}/traffic/referral-assessment",
5637
+ ...options
5638
+ });
5639
+ };
5518
5640
  var getApiV1ProjectsByNameTrafficEvents = (options) => {
5519
5641
  return (options.client ?? client).get({
5520
5642
  security: [
@@ -7157,8 +7279,18 @@ var ApiClient = class {
7157
7279
  async getTelemetry() {
7158
7280
  return normalizeTelemetryStatus(await this.invoke(() => getApiV1Telemetry({ client: this.heyClient })));
7159
7281
  }
7282
+ /**
7283
+ * Asks for every opt-in context field this build can read (older servers
7284
+ * ignore the header), then reads the page with the tolerant schema, so a
7285
+ * field added by a newer server is dropped rather than rejecting the page.
7286
+ */
7160
7287
  async listOperationalLogs(query = {}) {
7161
- return this.invoke(() => getApiV1OperationsLogs({ client: this.heyClient, query }));
7288
+ const page = await this.invoke(() => getApiV1OperationsLogs({
7289
+ client: this.heyClient,
7290
+ query,
7291
+ headers: { [OPERATIONAL_LOG_FIELDS_HEADER]: OPERATIONAL_LOG_OPT_IN_CONTEXT_FIELDS.join(",") }
7292
+ }));
7293
+ return operationalLogListReadSchema.parse(page);
7162
7294
  }
7163
7295
  async updateTelemetry(enabled) {
7164
7296
  return normalizeTelemetryStatus(await this.invoke(() => putApiV1Telemetry({ client: this.heyClient, body: { enabled } })));
@@ -7830,6 +7962,19 @@ var ApiClient = class {
7830
7962
  })
7831
7963
  );
7832
7964
  }
7965
+ async listGbpReviews(project, opts) {
7966
+ const query = {};
7967
+ if (opts?.locationName) query.locationName = opts.locationName;
7968
+ if (opts?.negative !== void 0) query.negative = String(opts.negative);
7969
+ if (opts?.limit !== void 0) query.limit = String(opts.limit);
7970
+ return this.invoke(
7971
+ () => getApiV1ProjectsByNameGbpReviews({
7972
+ client: this.heyClient,
7973
+ path: { name: project },
7974
+ query: Object.keys(query).length > 0 ? query : void 0
7975
+ })
7976
+ );
7977
+ }
7833
7978
  async getGbpSummary(project, opts) {
7834
7979
  return this.invoke(
7835
7980
  () => getApiV1ProjectsByNameGbpSummary({
@@ -7876,6 +8021,15 @@ var ApiClient = class {
7876
8021
  })
7877
8022
  );
7878
8023
  }
8024
+ async gscQueryTotals(project, params) {
8025
+ return this.invoke(
8026
+ () => getApiV1ProjectsByNameGoogleGscQueryTotals({
8027
+ client: this.heyClient,
8028
+ path: { name: project },
8029
+ query: params
8030
+ })
8031
+ );
8032
+ }
7879
8033
  async gscInspect(project, url) {
7880
8034
  return this.invoke(
7881
8035
  () => postApiV1ProjectsByNameGoogleGscInspect({
@@ -8250,6 +8404,13 @@ var ApiClient = class {
8250
8404
  })
8251
8405
  );
8252
8406
  }
8407
+ async trafficReferralAssessment(project, query) {
8408
+ return this.invoke(() => getApiV1ProjectsByNameTrafficReferralAssessment({
8409
+ client: this.heyClient,
8410
+ path: { name: project },
8411
+ query
8412
+ }));
8413
+ }
8253
8414
  async trafficListEvents(project, params) {
8254
8415
  return this.invoke(
8255
8416
  () => getApiV1ProjectsByNameTrafficEvents({
@@ -8846,7 +9007,10 @@ var ApiClient = class {
8846
9007
  );
8847
9008
  }
8848
9009
  async runDoctor(opts = {}) {
8849
- const checkQuery = opts.checkIds && opts.checkIds.length > 0 ? { check: opts.checkIds.join(",") } : void 0;
9010
+ const checkQuery = {
9011
+ ...opts.checkIds?.length ? { check: opts.checkIds.join(",") } : {},
9012
+ ...opts.reportMonth ? { reportMonth: opts.reportMonth } : {}
9013
+ };
8850
9014
  if (opts.project) {
8851
9015
  return this.invoke(
8852
9016
  () => getApiV1ProjectsByNameDoctor({
@@ -9138,7 +9302,7 @@ var CANONRY_MCP_TOOLKITS = [
9138
9302
  {
9139
9303
  name: "gsc",
9140
9304
  title: "Google Search Console",
9141
- description: "Read GSC performance, inspections, coverage, sitemaps, and deindexed URLs.",
9305
+ description: "Read GSC performance, per-query totals, inspections, coverage, sitemaps, and deindexed URLs.",
9142
9306
  whenToLoad: "Load when you need indexing, coverage, or sitemap data from Google Search Console."
9143
9307
  },
9144
9308
  {
@@ -9150,7 +9314,7 @@ var CANONRY_MCP_TOOLKITS = [
9150
9314
  {
9151
9315
  name: "gbp",
9152
9316
  title: "Google Business Profile",
9153
- description: "Local AEO signals: discover GBP locations under a connected account and toggle which ones sync. Future phases will add reviews, keyword impressions, daily performance metrics, and hotel attributes.",
9317
+ description: "Local AEO signals: discover GBP locations under a connected account and toggle which ones sync, then read daily performance metrics, search keywords, booking links, hotel and owner-set attributes, the public Places listing, and reviews with their alert state.",
9154
9318
  whenToLoad: "Load when the project tracks local search visibility or has connected Google Business Profile."
9155
9319
  },
9156
9320
  {
@@ -9180,8 +9344,8 @@ var CANONRY_MCP_TOOLKITS = [
9180
9344
  {
9181
9345
  name: "traffic",
9182
9346
  title: "Server-side traffic ingestion",
9183
- description: "Connect Cloud Run traffic sources, trigger syncs, and read crawler / AI-referral hourly rollups straight from server logs (no GA dependency).",
9184
- 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."
9347
+ description: "Read crawler / AI-referral hourly rollups straight from server logs (no GA dependency), assess AI-referral bursts from stored evidence (raw counts, candidate bursts, a separate adjusted estimate, coverage limits), connect Cloud Run / WordPress / Vercel sources, trigger syncs, and backfill Cloud Run / Vercel windows.",
9348
+ 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), when reviewing candidate AI-referral bursts before quoting server-side AI referral totals, or when wiring up / syncing a traffic source."
9185
9349
  },
9186
9350
  {
9187
9351
  name: "agent",
@@ -9982,6 +10146,10 @@ export {
9982
10146
  dashboardManagedRunKindsSchema,
9983
10147
  resolveOperatorApiKeyIds,
9984
10148
  getBootstrapEnv,
10149
+ providerConfigFromEntry,
10150
+ adapterSupportsBatch,
10151
+ batchEligibleProviderNames,
10152
+ providersWithUnsupportedBatch,
9985
10153
  getConfigDir,
9986
10154
  getConfigPath,
9987
10155
  loadConfig,