@canonry/canonry 4.177.3 → 4.178.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 (29) hide show
  1. package/assets/assets/{AuditHistoryPanel-YZvGU1la.js → AuditHistoryPanel-BCtMrEMF.js} +1 -1
  2. package/assets/assets/{BacklinksPage-CB2uJWWy.js → BacklinksPage-CIo2hA0i.js} +1 -1
  3. package/assets/assets/{ChartPrimitives-BoYe2M-i.js → ChartPrimitives-B_LDVvTy.js} +1 -1
  4. package/assets/assets/{HistoryPage-D9IxxbQ9.js → HistoryPage-D24U8cUG.js} +1 -1
  5. package/assets/assets/{MeasurementPropertyPage-CxgnnPdp.js → MeasurementPropertyPage-BKDdv-jJ.js} +1 -1
  6. package/assets/assets/ProjectPage-DrIs_ZuR.js +9 -0
  7. package/assets/assets/{RunRow-2KxOta8F.js → RunRow-B39IK7hK.js} +1 -1
  8. package/assets/assets/{RunsPage-ya8vTkyd.js → RunsPage-R4W1kD0B.js} +1 -1
  9. package/assets/assets/{SettingsPage-lTy3o2bo.js → SettingsPage-BAOGyt1F.js} +1 -1
  10. package/assets/assets/{SiteHealthSection-Cyu7MIv2.js → SiteHealthSection-Bx7yVNMQ.js} +3 -3
  11. package/assets/assets/{TrafficPage-DjhKfw57.js → TrafficPage-DL8RvM2R.js} +1 -1
  12. package/assets/assets/{TrafficSourceDetailPage-Pwi-Dl9Q.js → TrafficSourceDetailPage-COzjakZa.js} +1 -1
  13. package/assets/assets/{extract-error-message-I1FVWHLH.js → extract-error-message-B3TERCQ-.js} +1 -1
  14. package/assets/assets/{index-DQVTRT9J.css → index-D0GbiVhZ.css} +1 -1
  15. package/assets/assets/index-xtxQtZRo.js +83 -0
  16. package/assets/assets/{react-sigma_core.esm.min-BX6mOEq5.js → react-sigma_core.esm.min-CbXAujub.js} +1 -1
  17. package/assets/index.html +2 -2
  18. package/dist/{chunk-5EH666EO.js → chunk-JKKHGDDC.js} +3048 -2058
  19. package/dist/{chunk-PQT3ECM3.js → chunk-OYDIND7Q.js} +178 -1
  20. package/dist/{chunk-6XUWDSLN.js → chunk-UTW6QOGP.js} +1356 -907
  21. package/dist/{chunk-QRE3DAAU.js → chunk-VIVLYBFX.js} +2 -2
  22. package/dist/{chunk-7ABFIVKO.js → chunk-WINVGL5B.js} +458 -137
  23. package/dist/cli.js +87 -5
  24. package/dist/index.js +4 -4
  25. package/dist/{intelligence-service-CHZGHFGS.js → intelligence-service-YSRPTRKP.js} +2 -2
  26. package/dist/mcp.js +5 -380
  27. package/package.json +10 -10
  28. package/assets/assets/ProjectPage-CPmaXzhL.js +0 -9
  29. package/assets/assets/index-BeLVKN3H.js +0 -83
@@ -53,6 +53,9 @@ function quotaExceeded(metric, details) {
53
53
  function providerError(message, details) {
54
54
  return new AppError("PROVIDER_ERROR", message, 502, details);
55
55
  }
56
+ function providerAuthError(message, details) {
57
+ return new AppError("PROVIDER_AUTH", message, 502, details);
58
+ }
56
59
  function noProvider(projectName, details) {
57
60
  return new AppError(
58
61
  "NO_PROVIDER",
@@ -8305,6 +8308,84 @@ var googleAdsRawSnapshotDtoSchema = z20.object({
8305
8308
  context.addIssue({ code: z20.ZodIssueCode.custom, path: ["payload", "kind"], message: "Snapshot metadata and payload kinds must match." });
8306
8309
  }
8307
8310
  });
8311
+ var googleAdsMetricsWindowSchema = z20.enum(["7d", "14d", "30d"]);
8312
+ var googleAdsMetricTotalsSchema = z20.object({
8313
+ impressions: z20.number().int().nonnegative(),
8314
+ clicks: z20.number().int().nonnegative(),
8315
+ costMicros: z20.number().int().nonnegative(),
8316
+ /** FLOAT: Google reports fractional conversions, so 0.5 is a real value. */
8317
+ conversions: z20.number().nonnegative(),
8318
+ /** Null when no row in scope reported a value. */
8319
+ conversionValueMicros: z20.number().int().nonnegative().nullable(),
8320
+ /** clicks / impressions. Null when impressions === 0. */
8321
+ ctr: z20.number().nullable(),
8322
+ /** Math.round(costMicros / clicks). Null when clicks === 0. */
8323
+ cpcMicros: z20.number().int().nonnegative().nullable(),
8324
+ /** conversions / clicks. Null when clicks === 0. */
8325
+ conversionRate: z20.number().nullable(),
8326
+ /** Math.round(costMicros / conversions). Null when conversions === 0. */
8327
+ costPerConversionMicros: z20.number().int().nonnegative().nullable()
8328
+ });
8329
+ var googleAdsMetricsDailyPointSchema = z20.object({
8330
+ date: calendarDateSchema,
8331
+ origin: z20.enum(["provider", "filled"]),
8332
+ impressions: z20.number().int().nonnegative(),
8333
+ clicks: z20.number().int().nonnegative(),
8334
+ costMicros: z20.number().int().nonnegative(),
8335
+ conversions: z20.number().nonnegative(),
8336
+ ctr: z20.number().nullable()
8337
+ });
8338
+ var googleAdsCampaignPerformanceSchema = z20.object({
8339
+ campaignId: opaqueIdSchema,
8340
+ /** Null when the metrics snapshot names a campaign the inventory snapshot does not. */
8341
+ name: z20.string().nullable(),
8342
+ status: googleAdsCampaignStatusSchema,
8343
+ totals: googleAdsMetricTotalsSchema
8344
+ });
8345
+ var googleAdsPerformanceSourceSchema = z20.object({
8346
+ snapshotId: opaqueIdSchema,
8347
+ capturedAt: z20.string(),
8348
+ customerId: opaqueIdSchema,
8349
+ currencyCode: z20.string().nullable(),
8350
+ timeZone: z20.string().nullable(),
8351
+ /** Newest CLOSED day. Every window ends here. */
8352
+ asOfDate: calendarDateSchema,
8353
+ openDate: calendarDateSchema.nullable(),
8354
+ /** True when the provider row cap was hit, so totals are a subset sum. */
8355
+ truncated: z20.boolean(),
8356
+ campaignsQueried: z20.number().int().nonnegative(),
8357
+ campaignsInInventory: z20.number().int().nonnegative()
8358
+ });
8359
+ var googleAdsPerformancePeriodSchema = z20.object({
8360
+ startDate: calendarDateSchema,
8361
+ endDate: calendarDateSchema,
8362
+ days: z20.number().int().positive(),
8363
+ totals: googleAdsMetricTotalsSchema
8364
+ });
8365
+ var googleAdsPerformanceComparisonSchema = z20.object({
8366
+ days: z20.number().int().positive(),
8367
+ prior: googleAdsPerformancePeriodSchema,
8368
+ change: z20.object({
8369
+ impressions: z20.number().nullable(),
8370
+ clicks: z20.number().nullable(),
8371
+ costMicros: z20.number().nullable(),
8372
+ conversions: z20.number().nullable(),
8373
+ ctr: z20.number().nullable(),
8374
+ conversionRate: z20.number().nullable()
8375
+ })
8376
+ });
8377
+ var googleAdsPerformanceDtoSchema = z20.object({
8378
+ window: googleAdsMetricsWindowSchema,
8379
+ startDate: calendarDateSchema,
8380
+ endDate: calendarDateSchema,
8381
+ days: z20.number().int().positive(),
8382
+ totals: googleAdsMetricTotalsSchema,
8383
+ daily: z20.array(googleAdsMetricsDailyPointSchema),
8384
+ campaigns: z20.array(googleAdsCampaignPerformanceSchema),
8385
+ comparison: googleAdsPerformanceComparisonSchema.nullable(),
8386
+ comparisonUnavailableReason: z20.enum(["insufficient-history", "no-snapshot"]).nullable(),
8387
+ source: googleAdsPerformanceSourceSchema.nullable()
8388
+ });
8308
8389
 
8309
8390
  // ../contracts/src/google-tag-manager.ts
8310
8391
  import { z as z21 } from "zod";
@@ -8774,6 +8855,32 @@ var conversionTrackingIntegrityAssessmentDtoSchema = z22.object({
8774
8855
  findings: z22.array(conversionTrackingIntegrityFindingDtoSchema),
8775
8856
  evaluatedAt: z22.string()
8776
8857
  }).strict();
8858
+ var conversionTrackingOptionSchema = z22.object({
8859
+ id: opaqueIdSchema3,
8860
+ /** Human label the operator recognises, e.g. "Booking completed". */
8861
+ name: z22.string(),
8862
+ /** Secondary line: the Ads category, or the GTM tag type. */
8863
+ detail: z22.string(),
8864
+ /**
8865
+ * False when the option exists but is not a sensible target: a removed Ads
8866
+ * action, or a paused GTM tag. Offered but flagged, never silently hidden,
8867
+ * because a contract may legitimately point at one.
8868
+ */
8869
+ active: z22.boolean()
8870
+ });
8871
+ var conversionTrackingOptionsDtoSchema = z22.object({
8872
+ googleAds: z22.object({
8873
+ /** Null when Google Ads is not connected or no customer is selected. */
8874
+ customerId: opaqueIdSchema3.nullable(),
8875
+ syncedAt: z22.string().nullable(),
8876
+ conversionActions: z22.array(conversionTrackingOptionSchema)
8877
+ }),
8878
+ gtm: z22.object({
8879
+ containerId: opaqueIdSchema3.nullable(),
8880
+ syncedAt: z22.string().nullable(),
8881
+ tags: z22.array(conversionTrackingOptionSchema)
8882
+ })
8883
+ });
8777
8884
 
8778
8885
  // ../contracts/src/google-marketing.ts
8779
8886
  import { z as z23 } from "zod";
@@ -16053,6 +16160,44 @@ function serializeForInlineScript(value) {
16053
16160
  return JSON.stringify(value).replace(/</g, "\\u003c").replace(/>/g, "\\u003e").replace(/&/g, "\\u0026").replace(/\u2028/g, "\\u2028").replace(/\u2029/g, "\\u2029");
16054
16161
  }
16055
16162
 
16163
+ // ../contracts/src/provider-errors.ts
16164
+ var PROVIDER_ERROR_PRIORITY = [
16165
+ "PROVIDER_AUTH",
16166
+ "RATE_LIMITED",
16167
+ "TIMEOUT",
16168
+ "NETWORK",
16169
+ "PARSE_ERROR",
16170
+ "UNKNOWN"
16171
+ ];
16172
+ function classifyProviderErrorMessage(message) {
16173
+ if (/\b401\b|\b403\b|unauthorized|forbidden|invalid[_ -]?api[_ -]?key|missing[_ -]?api[_ -]?key|authentication/i.test(message)) {
16174
+ return "PROVIDER_AUTH";
16175
+ }
16176
+ if (/\b429\b|rate[_ -]?limit|too many requests|quota[_ -]?exceeded/i.test(message)) {
16177
+ return "RATE_LIMITED";
16178
+ }
16179
+ if (/timeout|timed out|ETIMEDOUT/i.test(message)) {
16180
+ return "TIMEOUT";
16181
+ }
16182
+ if (/ECONNRESET|ECONNREFUSED|ENOTFOUND|EAI_AGAIN|network|fetch failed|socket hang up/i.test(message)) {
16183
+ return "NETWORK";
16184
+ }
16185
+ if (/parse|unexpected token|invalid json|malformed|JSON\.parse/i.test(message)) {
16186
+ return "PARSE_ERROR";
16187
+ }
16188
+ return "UNKNOWN";
16189
+ }
16190
+ function classifyProviderErrorMessages(messages) {
16191
+ const codes = /* @__PURE__ */ new Set();
16192
+ for (const message of messages) {
16193
+ codes.add(classifyProviderErrorMessage(message));
16194
+ }
16195
+ for (const code of PROVIDER_ERROR_PRIORITY) {
16196
+ if (codes.has(code)) return code;
16197
+ }
16198
+ return "UNKNOWN";
16199
+ }
16200
+
16056
16201
  // ../contracts/src/telemetry.ts
16057
16202
  import { z as z54 } from "zod";
16058
16203
  var ONBOARDING_FLOW_VERSION = 1;
@@ -16091,12 +16236,24 @@ var onboardingBlockReasonSchema = z54.enum([
16091
16236
  "run_rejected",
16092
16237
  "run_failed",
16093
16238
  "run_cancelled",
16239
+ // Provider-side failures the query-generation step actually hits. Without
16240
+ // these every one of them reported `unknown`, which is why the queries step
16241
+ // was the only blocker nobody could diagnose.
16242
+ "rate_limited",
16243
+ "provider_auth",
16244
+ "network",
16094
16245
  "unknown"
16095
16246
  ]);
16247
+ var onboardingSurfaceSchema = z54.enum([
16248
+ "wizard",
16249
+ "platform",
16250
+ "site_health"
16251
+ ]);
16096
16252
  var onboardingEventBaseSchema = z54.object({
16097
16253
  eventId: z54.string().uuid(),
16098
16254
  flowVersion: z54.literal(ONBOARDING_FLOW_VERSION),
16099
- onboardingSessionId: z54.string().uuid()
16255
+ onboardingSessionId: z54.string().uuid(),
16256
+ surface: onboardingSurfaceSchema.optional()
16100
16257
  });
16101
16258
  var onboardingTelemetryEventSchema = z54.discriminatedUnion("event", [
16102
16259
  onboardingEventBaseSchema.extend({
@@ -16120,11 +16277,24 @@ var onboardingTelemetryEventSchema = z54.discriminatedUnion("event", [
16120
16277
  event: z54.literal("run.requested"),
16121
16278
  origin: z54.literal("dashboard_setup"),
16122
16279
  result: z54.enum(["queued", "rejected"]),
16280
+ /**
16281
+ * What kind of run was asked for. A site-health crawl has no providers and
16282
+ * no tracked queries, so its buckets are legitimately `0`; without this
16283
+ * field that is indistinguishable from a misconfigured visibility sweep.
16284
+ * Optional on the wire and defaulted at collection for the same reason as
16285
+ * `surface`: a documented fallback that nothing applies becomes a null
16286
+ * bucket downstream.
16287
+ */
16288
+ kind: z54.enum(["answer_visibility", "site_health"]).optional(),
16123
16289
  providerCountBucket: onboardingCountBucketSchema,
16124
16290
  queryCountBucket: onboardingCountBucketSchema,
16125
16291
  reasonCode: onboardingBlockReasonSchema.optional()
16126
16292
  }).strict()
16127
16293
  ]);
16294
+ function normalizeOnboardingEventForCollection(event) {
16295
+ const surfaced = { ...event, surface: event.surface ?? "wizard" };
16296
+ return surfaced.event === "run.requested" ? { ...surfaced, kind: surfaced.kind ?? "answer_visibility" } : surfaced;
16297
+ }
16128
16298
  var telemetryEventAcceptedDtoSchema = z54.object({
16129
16299
  accepted: z54.boolean()
16130
16300
  });
@@ -16169,6 +16339,7 @@ export {
16169
16339
  forbidden,
16170
16340
  quotaExceeded,
16171
16341
  providerError,
16342
+ providerAuthError,
16172
16343
  noProvider,
16173
16344
  noQueries,
16174
16345
  runInProgress,
@@ -16414,6 +16585,8 @@ export {
16414
16585
  googleAdsCampaignMetricsQuerySchema,
16415
16586
  GoogleAdsSnapshotKinds,
16416
16587
  googleAdsRawSnapshotDtoSchema,
16588
+ googleAdsMetricsWindowSchema,
16589
+ googleAdsPerformanceDtoSchema,
16417
16590
  GtmConnectionStates,
16418
16591
  gtmAccountsResponseSchema,
16419
16592
  gtmContainerListResponseSchema,
@@ -16434,6 +16607,7 @@ export {
16434
16607
  ConversionTrackingRuntimeObservations,
16435
16608
  deriveConversionTrackingIntegrityStatus,
16436
16609
  conversionTrackingIntegrityAssessmentDtoSchema,
16610
+ conversionTrackingOptionsDtoSchema,
16437
16611
  canonicalizeGtmAccountId,
16438
16612
  canonicalizeGtmContainerId,
16439
16613
  canonicalizeGoogleAdsCustomerSelection,
@@ -16849,9 +17023,12 @@ export {
16849
17023
  normalizeIdTokens,
16850
17024
  embedClientConfigForRequest,
16851
17025
  serializeForInlineScript,
17026
+ classifyProviderErrorMessage,
17027
+ classifyProviderErrorMessages,
16852
17028
  ONBOARDING_FLOW_VERSION,
16853
17029
  bucketOnboardingCount,
16854
17030
  onboardingTelemetryEventSchema,
17031
+ normalizeOnboardingEventForCollection,
16855
17032
  telemetryEventAcceptedDtoSchema,
16856
17033
  isGhostTelemetryEvent,
16857
17034
  MIN_TREND_POINTS,