@canonry/canonry 4.159.0 → 4.161.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 (30) hide show
  1. package/README.md +1 -1
  2. package/assets/agent-workspace/skills/aero/SKILL.md +16 -1
  3. package/assets/agent-workspace/skills/canonry/SKILL.md +17 -5
  4. package/assets/agent-workspace/skills/canonry/references/canonry-cli.md +66 -0
  5. package/assets/agent-workspace/skills/canonry/references/server-side-traffic.md +231 -62
  6. package/assets/assets/{AuditHistoryPanel-BiloGcQA.js → AuditHistoryPanel-C_1twF00.js} +1 -1
  7. package/assets/assets/{BacklinksPage-CPM1O2bC.js → BacklinksPage-CfAuMCaN.js} +1 -1
  8. package/assets/assets/{HistoryPage-1YOjtdJy.js → HistoryPage-DrRxOL3j.js} +1 -1
  9. package/assets/assets/{MeasurementPropertyPage-CVDTY_gC.js → MeasurementPropertyPage-BFtxx5Jw.js} +1 -1
  10. package/assets/assets/{ProjectPage-DnGXMx1n.js → ProjectPage-Djvhx4HD.js} +9 -9
  11. package/assets/assets/{RunRow-fIaadH4h.js → RunRow-DVZXibR2.js} +1 -1
  12. package/assets/assets/{RunsPage-DfifdM5z.js → RunsPage-CAUMy7By.js} +1 -1
  13. package/assets/assets/{SettingsPage-efA2EEmS.js → SettingsPage-CcSOmQAl.js} +1 -1
  14. package/assets/assets/{SiteHealthSection-BROtQGfu.js → SiteHealthSection-DYjEWd1I.js} +3 -3
  15. package/assets/assets/{TrafficPage-Wk43Bm_q.js → TrafficPage-BWM33jnJ.js} +1 -1
  16. package/assets/assets/{TrafficSourceDetailPage-BhBvoLWu.js → TrafficSourceDetailPage-DvEZ_JGY.js} +1 -1
  17. package/assets/assets/{extract-error-message-YGzZFvWs.js → extract-error-message-CnKOJkYB.js} +1 -1
  18. package/assets/assets/{index-DmsIZQAm.js → index-CQGAqmDx.js} +22 -22
  19. package/assets/assets/{react-sigma_core.esm.min-DM9XptbM.js → react-sigma_core.esm.min-CHCAIMBW.js} +1 -1
  20. package/assets/index.html +1 -1
  21. package/dist/{chunk-ZL3VY435.js → chunk-EXDO7EPL.js} +104 -9
  22. package/dist/{chunk-ZEG43TY2.js → chunk-HCGTKQCG.js} +21 -1
  23. package/dist/{chunk-5AFWHKKI.js → chunk-J27J2DF6.js} +2095 -703
  24. package/dist/{chunk-BZPBVOAM.js → chunk-W6OWEPZG.js} +70 -30
  25. package/dist/cli.js +308 -124
  26. package/dist/index.d.ts +28 -14
  27. package/dist/index.js +4 -4
  28. package/dist/{intelligence-service-DHY5CYWX.js → intelligence-service-HKDIVTZB.js} +2 -2
  29. package/dist/mcp.js +2 -2
  30. package/package.json +8 -7
@@ -10,12 +10,13 @@ import {
10
10
  loadConfig,
11
11
  loadConfigRaw,
12
12
  saveConfigPatch
13
- } from "./chunk-ZEG43TY2.js";
13
+ } from "./chunk-HCGTKQCG.js";
14
14
  import {
15
15
  CC_CACHE_DIR,
16
16
  DUCKDB_SPEC,
17
17
  GBP_DAILY_METRICS,
18
18
  GSC_DATA_LAG_DAYS,
19
+ GSC_REPORTING_TIME_ZONE,
19
20
  IntelligenceService,
20
21
  PLUGIN_DIR,
21
22
  adsAdGroups,
@@ -79,6 +80,7 @@ import {
79
80
  groupRunsByCreatedAt,
80
81
  gscCoverageSnapshots,
81
82
  gscDailyTotals,
83
+ gscDataWatermarks,
82
84
  gscQueryDailyTotals,
83
85
  gscSearchData,
84
86
  gscUrlInspections,
@@ -137,7 +139,7 @@ import {
137
139
  siteCrawlSnapshots,
138
140
  toAlertView,
139
141
  usageCounters
140
- } from "./chunk-5AFWHKKI.js";
142
+ } from "./chunk-J27J2DF6.js";
141
143
  import {
142
144
  AGENT_MEMORY_VALUE_MAX_BYTES,
143
145
  AGENT_PROVIDER_IDS,
@@ -191,6 +193,7 @@ import {
191
193
  bucketOnboardingCount,
192
194
  buildRunErrorFromMessages,
193
195
  classifySkillFile,
196
+ cloudflareQueueNameSchema,
194
197
  coerceSkillManifest,
195
198
  computeBacklinkSummaryMetrics,
196
199
  contentActionLabel,
@@ -235,6 +238,7 @@ import {
235
238
  resolveSnapshotRequestQueries,
236
239
  serializeForInlineScript,
237
240
  serializeRunError,
241
+ shiftIsoCalendarDate,
238
242
  siteAuditRequestIdentity,
239
243
  skillsClientSchema,
240
244
  splitList,
@@ -246,7 +250,7 @@ import {
246
250
  validationError,
247
251
  winnabilityClassLabel,
248
252
  withRetry
249
- } from "./chunk-ZL3VY435.js";
253
+ } from "./chunk-EXDO7EPL.js";
250
254
 
251
255
  // src/telemetry.ts
252
256
  import crypto from "crypto";
@@ -3187,29 +3191,33 @@ function ensureConnections6(config) {
3187
3191
  if (!config.cloudflareTraffic.connections) config.cloudflareTraffic.connections = [];
3188
3192
  return config.cloudflareTraffic.connections;
3189
3193
  }
3190
- function normalizeDirectPushConnection(connection) {
3194
+ function normalizeCloudflareTrafficConnection(connection) {
3191
3195
  const deliveryMode = connection.deliveryMode;
3192
- if (deliveryMode !== void 0 && deliveryMode !== "direct-push") {
3193
- throw unsupportedDeliveryMode(deliveryMode);
3196
+ if (deliveryMode === "queue-pull") {
3197
+ const queue = connection;
3198
+ if (typeof queue.apiToken !== "string" || queue.apiToken.length === 0 || typeof queue.accountId !== "string" || queue.accountId.length === 0 || typeof queue.queueId !== "string" || queue.queueId.length === 0 || typeof queue.queueName !== "string" || !cloudflareQueueNameSchema.safeParse(queue.queueName).success || typeof queue.retentionSeconds !== "number" || !Number.isInteger(queue.retentionSeconds) || queue.retentionSeconds < 60 || queue.retentionSeconds > 1209600) {
3199
+ throw new Error("Invalid Cloudflare queue-pull credential configuration");
3200
+ }
3201
+ return connection;
3194
3202
  }
3195
3203
  if (deliveryMode === "direct-push") return connection;
3196
- return { ...connection, deliveryMode: "direct-push" };
3204
+ if (deliveryMode === void 0) {
3205
+ return { ...connection, deliveryMode: "direct-push" };
3206
+ }
3207
+ throw unsupportedDeliveryMode(deliveryMode);
3197
3208
  }
3198
3209
  function getCloudflareTrafficConnection(config, projectName) {
3199
3210
  const connection = (config.cloudflareTraffic?.connections ?? []).find((c) => c.projectName === projectName);
3200
- return connection ? normalizeDirectPushConnection(connection) : void 0;
3211
+ return connection ? normalizeCloudflareTrafficConnection(connection) : void 0;
3201
3212
  }
3202
3213
  function getCloudflareTrafficConnectionBySourceId(config, sourceId) {
3203
3214
  const connection = (config.cloudflareTraffic?.connections ?? []).find((c) => c.sourceId === sourceId);
3204
- return connection ? normalizeDirectPushConnection(connection) : void 0;
3215
+ return connection ? normalizeCloudflareTrafficConnection(connection) : void 0;
3205
3216
  }
3206
3217
  function upsertCloudflareTrafficConnection(config, connection) {
3207
- const deliveryMode = connection.deliveryMode;
3208
- if (deliveryMode !== "direct-push") {
3209
- throw unsupportedDeliveryMode(deliveryMode);
3210
- }
3218
+ normalizeCloudflareTrafficConnection(connection);
3211
3219
  const connections = ensureConnections6(config);
3212
- const index = connections.findIndex((c) => c.projectName === connection.projectName);
3220
+ const index = connections.findIndex((c) => c.sourceId === connection.sourceId);
3213
3221
  if (index === -1) {
3214
3222
  connections.push(connection);
3215
3223
  return connection;
@@ -3217,6 +3225,16 @@ function upsertCloudflareTrafficConnection(config, connection) {
3217
3225
  connections[index] = connection;
3218
3226
  return connection;
3219
3227
  }
3228
+ function removeCloudflareTrafficConnectionBySourceId(config, sourceId) {
3229
+ const connections = config.cloudflareTraffic?.connections;
3230
+ if (!connections?.length) return false;
3231
+ const next = connections.filter((c) => c.sourceId !== sourceId);
3232
+ if (next.length === connections.length) return false;
3233
+ if (!config.cloudflareTraffic) return false;
3234
+ config.cloudflareTraffic.connections = next;
3235
+ if (next.length === 0) delete config.cloudflareTraffic;
3236
+ return true;
3237
+ }
3220
3238
  function removeCloudflareTrafficConnection(config, projectName) {
3221
3239
  const connections = config.cloudflareTraffic?.connections;
3222
3240
  if (!connections?.length) return false;
@@ -4413,14 +4431,6 @@ function writeCoverageSnapshot(db, projectId, runId, opts = {}) {
4413
4431
 
4414
4432
  // src/gsc-sync.ts
4415
4433
  var log2 = createLogger("GscSync");
4416
- function formatDate(d) {
4417
- return d.toISOString().split("T")[0];
4418
- }
4419
- function daysAgo(n) {
4420
- const d = /* @__PURE__ */ new Date();
4421
- d.setDate(d.getDate() - n);
4422
- return d;
4423
- }
4424
4434
  async function executeGscSync(db, runId, projectId, opts) {
4425
4435
  const now = (/* @__PURE__ */ new Date()).toISOString();
4426
4436
  db.update(runs).set({ status: "running", startedAt: now }).where(eq4(runs.id, runId)).run();
@@ -4454,9 +4464,9 @@ async function executeGscSync(db, runId, projectId, opts) {
4454
4464
  saveConfigPatch(opts.config);
4455
4465
  }
4456
4466
  const lagOffset = GSC_DATA_LAG_DAYS;
4457
- const endDate = formatDate(daysAgo(lagOffset));
4467
+ const endDate = formatIsoDateInTimeZone((/* @__PURE__ */ new Date()).toISOString(), GSC_REPORTING_TIME_ZONE);
4458
4468
  const days = opts.full ? 480 : opts.days ?? 30;
4459
- const startDate = formatDate(daysAgo(days + lagOffset));
4469
+ const startDate = shiftIsoCalendarDate(endDate, -(days + lagOffset));
4460
4470
  log2.info("fetch.start", { runId, projectId, propertyId: conn.propertyId, startDate, endDate });
4461
4471
  const rows = await fetchSearchAnalytics(accessToken, conn.propertyId, {
4462
4472
  startDate,
@@ -4518,7 +4528,29 @@ async function executeGscSync(db, runId, projectId, opts) {
4518
4528
  createdAt: dailyTotalsNow
4519
4529
  }).run();
4520
4530
  }
4521
- log2.info("daily-totals.complete", { runId, projectId, rowCount: totalRows.length });
4531
+ const observedThrough = totalRows.map((row) => row.keys[0] ?? "").filter((date) => date !== "").reduce((max, date) => max === null || date > max ? date : max, null);
4532
+ if (observedThrough !== null || endDate) {
4533
+ const existing = db.select().from(gscDataWatermarks).where(eq4(gscDataWatermarks.projectId, projectId)).get();
4534
+ const nextThrough = [existing?.dataThroughDate ?? null, observedThrough].filter((d) => d !== null).reduce((max, d) => max === null || d > max ? d : max, null);
4535
+ if (nextThrough !== null) {
4536
+ db.insert(gscDataWatermarks).values({
4537
+ projectId,
4538
+ dataThroughDate: nextThrough,
4539
+ syncedThroughDate: endDate,
4540
+ updatedAt: dailyTotalsNow
4541
+ }).onConflictDoUpdate({
4542
+ target: gscDataWatermarks.projectId,
4543
+ set: { dataThroughDate: nextThrough, syncedThroughDate: endDate, updatedAt: dailyTotalsNow }
4544
+ }).run();
4545
+ }
4546
+ }
4547
+ log2.info("daily-totals.complete", {
4548
+ runId,
4549
+ projectId,
4550
+ rowCount: totalRows.length,
4551
+ observedThrough,
4552
+ syncedThrough: endDate
4553
+ });
4522
4554
  const queryTotalRows = await fetchSearchAnalytics(accessToken, propertyId, {
4523
4555
  startDate,
4524
4556
  endDate,
@@ -4570,7 +4602,7 @@ var DEFAULT_DAYS_OF_METRICS = 30;
4570
4602
  var DEFAULT_MONTHS_OF_KEYWORDS = 12;
4571
4603
  var KEYWORD_TREND_MONTHS = 3;
4572
4604
  var KEYWORD_HISTORY_RETENTION_MONTHS = 18;
4573
- function daysAgo2(n) {
4605
+ function daysAgo(n) {
4574
4606
  const d = /* @__PURE__ */ new Date();
4575
4607
  d.setUTCDate(d.getUTCDate() - n);
4576
4608
  return d;
@@ -4618,8 +4650,8 @@ async function executeGbpSync(db, runId, projectId, opts) {
4618
4650
  locationRows = await refreshSelectedLocationProfiles(db, projectId, accessToken, locationRows);
4619
4651
  const daysOfMetrics = opts.daysOfMetrics ?? DEFAULT_DAYS_OF_METRICS;
4620
4652
  const monthsOfKeywords = opts.monthsOfKeywords ?? DEFAULT_MONTHS_OF_KEYWORDS;
4621
- const metricsStart = daysAgo2(daysOfMetrics);
4622
- const metricsEnd = daysAgo2(1);
4653
+ const metricsStart = daysAgo(daysOfMetrics);
4654
+ const metricsEnd = daysAgo(1);
4623
4655
  const keywordsStart = monthMinus(monthsOfKeywords);
4624
4656
  const keywordsEnd = monthMinus(0);
4625
4657
  const trendMonths = Array.from({ length: KEYWORD_TREND_MONTHS }, (_, i) => monthMinus(i + 1));
@@ -9002,7 +9034,7 @@ function readStoredGroundingSources(rawResponse) {
9002
9034
  return result;
9003
9035
  }
9004
9036
  async function backfillInsightsCommand(project, opts) {
9005
- const { IntelligenceService: IntelligenceService2 } = await import("./intelligence-service-DHY5CYWX.js");
9037
+ const { IntelligenceService: IntelligenceService2 } = await import("./intelligence-service-HKDIVTZB.js");
9006
9038
  const config = loadConfig();
9007
9039
  const db = createClient(config.database);
9008
9040
  migrate(db);
@@ -14655,6 +14687,14 @@ async function createServer(opts) {
14655
14687
  const removed = removeCloudflareTrafficConnection(opts.config, projectName);
14656
14688
  if (removed) saveConfigPatch(opts.config);
14657
14689
  return removed;
14690
+ },
14691
+ deleteConnectionBySourceId: (sourceId) => {
14692
+ const removed = removeCloudflareTrafficConnectionBySourceId(
14693
+ opts.config,
14694
+ sourceId
14695
+ );
14696
+ if (removed) saveConfigPatch(opts.config);
14697
+ return removed;
14658
14698
  }
14659
14699
  };
14660
14700
  const googleStateSecret = process.env.GOOGLE_STATE_SECRET ?? crypto25.randomBytes(32).toString("hex");
@@ -15710,7 +15750,7 @@ export {
15710
15750
  backfillInsightsCommand,
15711
15751
  backfillSnapshotAttributionCommand,
15712
15752
  backfillTrafficClassificationCommand,
15713
- getCloudflareTrafficConnection,
15753
+ getCloudflareTrafficConnectionBySourceId,
15714
15754
  setGoogleAuthConfig,
15715
15755
  installSkills,
15716
15756
  listSkills,