@canonry/canonry 7.44.1 → 7.45.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 (36) hide show
  1. package/assets/agent-workspace/skills/canonry/references/canonry-cli.md +10 -0
  2. package/assets/agent-workspace/skills/canonry/references/google-business-profile.md +3 -3
  3. package/assets/assets/{AuditHistoryPanel-CvANw3ds.js → AuditHistoryPanel-BJDLPf4D.js} +1 -1
  4. package/assets/assets/{BacklinksPage-C6x9ELjk.js → BacklinksPage-BDbYMh4s.js} +1 -1
  5. package/assets/assets/{HistoryPage-r36HX1cC.js → HistoryPage-B9c7cjV4.js} +1 -1
  6. package/assets/assets/{MeasurementPropertyPage-ComoCzR4.js → MeasurementPropertyPage-B2wDvzLz.js} +1 -1
  7. package/assets/assets/{ProjectPage-CIeU-buk.js → ProjectPage-Cgj5ZmRt.js} +1 -1
  8. package/assets/assets/{RunsPage-DI6eJATZ.js → RunsPage-DNJpOT2C.js} +1 -1
  9. package/assets/assets/{SettingsPage-Bw7GdXxs.js → SettingsPage-BJABQP0W.js} +1 -1
  10. package/assets/assets/{SiteHealthSection-C-JaNKpS.js → SiteHealthSection-Co-YnYL1.js} +3 -3
  11. package/assets/assets/{TrafficPage-Cnsp276v.js → TrafficPage-DGks1U43.js} +1 -1
  12. package/assets/assets/{TrafficSourceDetailPage-CBIaJk7e.js → TrafficSourceDetailPage-B9EC-koW.js} +1 -1
  13. package/assets/assets/{extract-error-message-C_Owa0n9.js → extract-error-message-BnQj6MRg.js} +1 -1
  14. package/assets/assets/{index-ZS9sSTMS.js → index-CQ2txiby.js} +3 -3
  15. package/assets/assets/{react-sigma_core.esm.min-ugyh-ooq.js → react-sigma_core.esm.min-DMBVhOEe.js} +1 -1
  16. package/assets/assets/{v2-overview-adapter-BLSrVQ7K.js → v2-overview-adapter-DUYXYO7p.js} +1 -1
  17. package/assets/index.html +1 -1
  18. package/dist/{chunk-SW54HXSZ.js → chunk-55QNMM7V.js} +3 -3
  19. package/dist/{chunk-5LY7EG4U.js → chunk-5A57TIOK.js} +2 -2
  20. package/dist/{chunk-GZ2KIONF.js → chunk-6333IHPS.js} +26 -0
  21. package/dist/{chunk-MPWBFKGK.js → chunk-E7BG7QGP.js} +87 -68
  22. package/dist/{chunk-JVBI6VBT.js → chunk-EJTCZGU3.js} +2 -2
  23. package/dist/{chunk-LK7O7RM6.js → chunk-GCBMBG2Y.js} +227 -41
  24. package/dist/{chunk-45Z5RJZW.js → chunk-KMMOYVAO.js} +3 -3
  25. package/dist/{chunk-3JVF3ULD.js → chunk-KZS5N3JH.js} +1 -1
  26. package/dist/{chunk-57MGI2UT.js → chunk-PIL3NHER.js} +25 -83
  27. package/dist/{chunk-G47XJVAS.js → chunk-XFBY4DJV.js} +101 -27
  28. package/dist/{cli-catalog-PNJEQV5H.js → cli-catalog-E45QWSSR.js} +3 -3
  29. package/dist/cli-commands-I5YOZVO6.js +15 -0
  30. package/dist/cli.js +10 -10
  31. package/dist/{demo-server-WRHR25HF.js → demo-server-2ZRO7T3Z.js} +5 -5
  32. package/dist/index.js +6 -6
  33. package/dist/{intelligence-service-QXXRUB2G.js → intelligence-service-JIFXDUUC.js} +2 -2
  34. package/dist/mcp.js +4 -4
  35. package/package.json +12 -12
  36. package/dist/cli-commands-D3JIQ2ID.js +0 -15
@@ -34,6 +34,7 @@ import {
34
34
  AiReferralTrafficClasses,
35
35
  AppError,
36
36
  BacklinkSources,
37
+ CHECK_RUNTIME_ERROR_SUFFIX,
37
38
  COMPETITOR_ALIAS_MAX_LENGTH,
38
39
  COMPETITOR_BLOCKED_ALIAS_LIMIT,
39
40
  COMPETITOR_BULK_ADD_REFUSAL_REASON,
@@ -482,6 +483,7 @@ import {
482
483
  googleMarketingOAuthConnectRequestSchema,
483
484
  googleMarketingOAuthConnectResponseSchema,
484
485
  googleMarketingProviderSchema,
486
+ googleOAuthStartResponseSchema,
485
487
  gradedReportMonths,
486
488
  groupIsoDateRanges,
487
489
  gscCoverageSnapshotDtoSchema,
@@ -911,7 +913,7 @@ import {
911
913
  wordpressSchemaDeployResultDtoSchema,
912
914
  wordpressSchemaStatusResultDtoSchema,
913
915
  wordpressStatusDtoSchema
914
- } from "./chunk-GZ2KIONF.js";
916
+ } from "./chunk-6333IHPS.js";
915
917
 
916
918
  // src/intelligence-service.ts
917
919
  import { eq as eq99, desc as desc45, asc as asc20, and as and82, ne as ne17, or as or24, inArray as inArray40, gte as gte26, lte as lte23, isNull as isNull19, sql as sql37, exists as exists2 } from "drizzle-orm";
@@ -1845,7 +1847,17 @@ var doctorHealthState = sqliteTable("doctor_health_state", {
1845
1847
  */
1846
1848
  notifiedSignature: text("notified_signature"),
1847
1849
  /** Triggering breaches owed by an unaccepted degraded alert, as `status:code:id`. */
1848
- pendingSignature: text("pending_signature")
1850
+ pendingSignature: text("pending_signature"),
1851
+ /**
1852
+ * The urgent problems a `health.urgent` subscriber has been told about and
1853
+ * that have not cleared since, as `status:code:id`. A problem in this set is
1854
+ * not news again; when the set empties, `health.urgent-resolved` is sent.
1855
+ * Kept apart from `notifiedSignature` because the two alerts go to different
1856
+ * webhooks and are accepted independently. NULL while nothing is outstanding.
1857
+ */
1858
+ urgentNotified: text("urgent_notified"),
1859
+ /** Urgent delivery histories by notification id and destination, never inherited by replacements. */
1860
+ urgentReceipts: text("urgent_receipts", { mode: "json" }).$type()
1849
1861
  });
1850
1862
  var siteLivenessState = sqliteTable("site_liveness_state", {
1851
1863
  projectId: text("project_id").primaryKey(),
@@ -1857,7 +1869,17 @@ var siteLivenessState = sqliteTable("site_liveness_state", {
1857
1869
  consecutiveFailures: integer("consecutive_failures").notNull().default(0),
1858
1870
  checkedAt: text("checked_at").notNull(),
1859
1871
  /** Set when an outage was actually paged; cleared on recovery. */
1860
- notifiedAt: text("notified_at")
1872
+ notifiedAt: text("notified_at"),
1873
+ /**
1874
+ * Set when a webhook scoped to urgent events accepted the outage, cleared
1875
+ * when one accepts the recovery or none is left to tell. Kept apart from
1876
+ * `notifiedAt` because those webhooks accept or refuse independently of the
1877
+ * others, and unlike it this survives the ok pass, so a refused "back up" is
1878
+ * still owed.
1879
+ */
1880
+ urgentNotifiedAt: text("urgent_notified_at"),
1881
+ /** Per-recipient outage receipts; the timestamp above summarizes outstanding receipts. */
1882
+ urgentReceipts: text("urgent_receipts", { mode: "json" }).$type()
1861
1883
  });
1862
1884
  var notifications = sqliteTable("notifications", {
1863
1885
  id: text("id").primaryKey(),
@@ -8632,6 +8654,32 @@ var MIGRATION_VERSIONS = [
8632
8654
  statements: [
8633
8655
  `ALTER TABLE site_crawl_snapshots ADD COLUMN issue_evidence TEXT`
8634
8656
  ]
8657
+ },
8658
+ {
8659
+ // The urgent problems a health.urgent subscriber was last told about. NULL
8660
+ // on every existing row: nothing has been sent, so a problem already open
8661
+ // when this ships is reported once to a webhook that subscribes.
8662
+ version: 181,
8663
+ name: "doctor-health-urgent-notified",
8664
+ statements: [
8665
+ `ALTER TABLE doctor_health_state ADD COLUMN urgent_notified TEXT`
8666
+ ]
8667
+ },
8668
+ {
8669
+ // The same record for the website liveness loop, which keeps its own row.
8670
+ version: 182,
8671
+ name: "site-liveness-urgent-notified-at",
8672
+ statements: [
8673
+ `ALTER TABLE site_liveness_state ADD COLUMN urgent_notified_at TEXT`
8674
+ ]
8675
+ },
8676
+ {
8677
+ version: 183,
8678
+ name: "urgent-health-recipient-receipts",
8679
+ statements: [
8680
+ `ALTER TABLE doctor_health_state ADD COLUMN urgent_receipts TEXT`,
8681
+ `ALTER TABLE site_liveness_state ADD COLUMN urgent_receipts TEXT`
8682
+ ]
8635
8683
  }
8636
8684
  ];
8637
8685
  var AERO_LEDGER_REBUILDS = [
@@ -16334,7 +16382,12 @@ var AlertFieldLabels = {
16334
16382
  replied: "Replied",
16335
16383
  source: "Source"
16336
16384
  };
16337
- var HEALTH_EVENTS = /* @__PURE__ */ new Set(["health.degraded", "health.recovered"]);
16385
+ var HEALTH_EVENTS = /* @__PURE__ */ new Set([
16386
+ "health.degraded",
16387
+ "health.recovered",
16388
+ "health.urgent",
16389
+ "health.urgent-resolved"
16390
+ ]);
16338
16391
  function isHealth(payload) {
16339
16392
  return HEALTH_EVENTS.has(payload.event);
16340
16393
  }
@@ -16348,10 +16401,15 @@ function bulletList(lines) {
16348
16401
  }
16349
16402
  function healthView(payload) {
16350
16403
  const { health, project } = payload;
16351
- const recovered = payload.event === "health.recovered";
16352
- const severity = recovered ? AlertSeverities.success : health.status === "fail" ? AlertSeverities.critical : AlertSeverities.warning;
16404
+ const urgentEvent = payload.event === "health.urgent" || payload.event === "health.urgent-resolved";
16405
+ const recovered = payload.event === "health.recovered" || payload.event === "health.urgent-resolved";
16406
+ const severity = recovered ? AlertSeverities.success : urgentEvent || health.status === "fail" ? AlertSeverities.critical : AlertSeverities.warning;
16353
16407
  const fields = [
16354
- { label: AlertFieldLabels.status, value: recovered ? "recovered" : health.status, compact: true },
16408
+ {
16409
+ label: AlertFieldLabels.status,
16410
+ value: recovered ? urgentEvent ? "resolved" : "recovered" : urgentEvent ? "urgent" : health.status,
16411
+ compact: true
16412
+ },
16355
16413
  { label: AlertFieldLabels.check, value: health.code, compact: true }
16356
16414
  ];
16357
16415
  if (health.previousStatus) {
@@ -16387,7 +16445,7 @@ function healthView(payload) {
16387
16445
  const website = health.code.startsWith("site.reachability.");
16388
16446
  return {
16389
16447
  severity,
16390
- title: website ? recovered ? `${project.name} website is back up` : `${project.name} website is down` : recovered ? `${project.name} recovered` : `${project.name} \u2014 measurement degraded`,
16448
+ title: website ? recovered ? `${project.name} website is back up` : `${project.name} website is down` : urgentEvent ? recovered ? `${project.name}: urgent problem resolved` : `${project.name}: urgent problem` : recovered ? `${project.name} recovered` : `${project.name} \u2014 measurement degraded`,
16391
16449
  body: health.summary,
16392
16450
  fields,
16393
16451
  url: payload.dashboardUrl,
@@ -40324,6 +40382,7 @@ var SCHEMA_TABLE = {
40324
40382
  GoogleMarketingDisconnectResponse: googleMarketingDisconnectResponseSchema,
40325
40383
  GoogleMarketingOAuthConnectRequest: googleMarketingOAuthConnectRequestSchema,
40326
40384
  GoogleMarketingOAuthConnectResponse: googleMarketingOAuthConnectResponseSchema,
40385
+ GoogleOAuthStartResponse: googleOAuthStartResponseSchema,
40327
40386
  GscCoverageSnapshotDto: gscCoverageSnapshotDtoSchema,
40328
40387
  GscCoverageSummaryDto: gscCoverageSummaryDtoSchema,
40329
40388
  GscDeindexedRowDto: gscDeindexedRowSchema,
@@ -44469,7 +44528,7 @@ var routeCatalog = [
44469
44528
  }
44470
44529
  },
44471
44530
  responses: {
44472
- 200: rawJsonResponse("Google auth URL returned.", { type: "object", properties: { url: { type: "string" } } }),
44531
+ 200: jsonResponse("Google auth URL returned.", "GoogleOAuthStartResponse"),
44473
44532
  400: errorResponse("Invalid Google connection request.")
44474
44533
  }
44475
44534
  },
@@ -51027,6 +51086,7 @@ async function fetchSearchLandingPages(accessToken, propertyId, options = {}) {
51027
51086
  var GBP_SCOPE = "https://www.googleapis.com/auth/business.manage";
51028
51087
  var GBP_ACCOUNT_MANAGEMENT_BASE = "https://mybusinessaccountmanagement.googleapis.com/v1";
51029
51088
  var GBP_BUSINESS_INFO_BASE = "https://mybusinessbusinessinformation.googleapis.com/v1";
51089
+ var GBP_PLACE_ACTIONS_BASE = "https://mybusinessplaceactions.googleapis.com/v1";
51030
51090
  var GBP_LEGACY_V4_BASE = "https://mybusiness.googleapis.com/v4";
51031
51091
  var GBP_PERFORMANCE_BASE = "https://businessprofileperformance.googleapis.com/v1";
51032
51092
  var GBP_LODGING_BASE = "https://mybusinesslodging.googleapis.com/v1";
@@ -51296,7 +51356,7 @@ async function listPlaceActionLinks(accessToken, locationName, opts = {}) {
51296
51356
  let pageToken;
51297
51357
  let page3 = 0;
51298
51358
  do {
51299
- const url = new URL(`${GBP_BUSINESS_INFO_BASE}/${locationName}/placeActionLinks`);
51359
+ const url = new URL(`${GBP_PLACE_ACTIONS_BASE}/${locationName}/placeActionLinks`);
51300
51360
  url.searchParams.set("pageSize", String(GBP_DEFAULT_PAGE_SIZE));
51301
51361
  if (pageToken) url.searchParams.set("pageToken", pageToken);
51302
51362
  const res = await gbpFetchGet(url.toString(), accessToken, opts);
@@ -51560,6 +51620,18 @@ function isSitemapOwnedByProperty(sitemapUrl, propertyId, canonicalDomain) {
51560
51620
  return false;
51561
51621
  }
51562
51622
  }
51623
+ function googleConnectionDto(connection) {
51624
+ return {
51625
+ id: `${connection.domain}:${connection.connectionType}`,
51626
+ domain: connection.domain,
51627
+ connectionType: connection.connectionType,
51628
+ propertyId: connection.propertyId ?? null,
51629
+ sitemapUrl: connection.sitemapUrl ?? null,
51630
+ scopes: connection.scopes ?? [],
51631
+ createdAt: connection.createdAt,
51632
+ updatedAt: connection.updatedAt
51633
+ };
51634
+ }
51563
51635
  async function getValidToken(store, domain, connectionType, clientId, clientSecret) {
51564
51636
  const conn = store.getConnection(domain, connectionType);
51565
51637
  if (!conn) {
@@ -51693,16 +51765,7 @@ async function googleRoutes(app, opts) {
51693
51765
  app.get("/projects/:name/google/connections", async (request) => {
51694
51766
  const project = resolveProject(app.db, request.params.name);
51695
51767
  const conns = opts.googleConnectionStore?.listConnections(project.canonicalDomain) ?? [];
51696
- return conns.map((connection) => ({
51697
- id: `${connection.domain}:${connection.connectionType}`,
51698
- domain: connection.domain,
51699
- connectionType: connection.connectionType,
51700
- propertyId: connection.propertyId ?? null,
51701
- sitemapUrl: connection.sitemapUrl ?? null,
51702
- scopes: connection.scopes ?? [],
51703
- createdAt: connection.createdAt,
51704
- updatedAt: connection.updatedAt
51705
- }));
51768
+ return conns.map(googleConnectionDto);
51706
51769
  });
51707
51770
  app.post("/projects/:name/google/connect", connectionRoute(app, (request) => {
51708
51771
  const integration = googleIntegration(request.body?.type);
@@ -52637,7 +52700,7 @@ async function googleRoutes(app, opts) {
52637
52700
  if (!conn) {
52638
52701
  throw notFound("Google connection", request.params.type);
52639
52702
  }
52640
- return { sitemapUrl: sitemapUrl.trim() };
52703
+ return googleConnectionDto(conn);
52641
52704
  });
52642
52705
  app.put("/projects/:name/google/connections/:type/property", connectionRoute(app, (request) => {
52643
52706
  const integration = googleIntegration(request.params.type);
@@ -52658,7 +52721,7 @@ async function googleRoutes(app, opts) {
52658
52721
  attempt.failed(void 0, "NOT_CONNECTED");
52659
52722
  throw notFound("Google connection", request.params.type);
52660
52723
  }
52661
- return { propertyId };
52724
+ return googleConnectionDto(conn);
52662
52725
  }));
52663
52726
  app.post("/projects/:name/google/indexing/request", async (request) => {
52664
52727
  const { clientId: googleClientId, clientSecret: googleClientSecret } = getAuthConfig();
@@ -86736,6 +86799,7 @@ var GA_DATA_STALE_DAYS = 5;
86736
86799
  var GSC_DATA_AGING_DAYS = 5;
86737
86800
  var GSC_DATA_STALE_DAYS = 7;
86738
86801
  var SYNC_IDLE_DAYS = 3;
86802
+ var NOT_SYNCING_URGENT_DAYS = 8;
86739
86803
  var GSC_REPORTING_TIME_ZONE2 = "America/Los_Angeles";
86740
86804
  var DAY_MS2 = 24 * 60 * 60 * 1e3;
86741
86805
  var ISO_DATE = /^(\d{4})-(\d{2})-(\d{2})$/;
@@ -86802,15 +86866,21 @@ function grade(ctx, spec, newestDate) {
86802
86866
  return {
86803
86867
  status: CheckStatuses.warn,
86804
86868
  code: code("not-syncing"),
86869
+ // The daily numbers have a real gap and nothing has fetched them for
86870
+ // longer than any schedule would leave them.
86871
+ ...age >= spec.staleDays && (syncAge === null || syncAge >= NOT_SYNCING_URGENT_DAYS) ? { urgent: true } : {},
86805
86872
  summary: `No ${spec.label} sync has completed in ${syncAge === null ? "any recorded run" : `${syncAge} days`}, and stored data ends ${newestDate}.`,
86806
86873
  remediation: `Run \`${sync}\`, or set a data-refresh schedule: \`canonry schedule set ${projectName} --kind data-refresh --preset daily\`.`,
86807
86874
  details
86808
86875
  };
86809
86876
  }
86810
86877
  const remediation = `${spec.quietExplanation} ${spec.brokenExplanation}`;
86878
+ const stale = age >= spec.staleDays;
86811
86879
  return {
86812
86880
  status: CheckStatuses.warn,
86813
- code: code(age >= spec.staleDays ? "stale" : "aging"),
86881
+ code: code(stale ? "stale" : "aging"),
86882
+ // Aging data is often a quiet site; stale data is a gap in the record.
86883
+ ...stale ? { urgent: true } : {},
86814
86884
  summary: `${spec.label} syncs are running but have stored nothing newer than ${newestDate} (${age} days).`,
86815
86885
  remediation,
86816
86886
  details
@@ -87122,6 +87192,7 @@ var siteReachabilityCheck = {
87122
87192
  return {
87123
87193
  status: CheckStatuses.fail,
87124
87194
  code: "site.reachability.refused-address",
87195
+ urgent: true,
87125
87196
  summary: `${url} resolves only to addresses that cannot serve visitors: ${result.reason}.`,
87126
87197
  remediation: "Check the domain registration and its DNS records. A suspended or parked domain resolves this way.",
87127
87198
  details: { url, finalUrl: result.finalUrl, reason: result.reason, attempts: result.attempts, durationMs: result.durationMs }
@@ -87130,8 +87201,9 @@ var siteReachabilityCheck = {
87130
87201
  return {
87131
87202
  status: CheckStatuses.fail,
87132
87203
  code: "site.reachability.down",
87204
+ urgent: true,
87133
87205
  summary: `${url} is not responding: ${result.reason}.`,
87134
- remediation: "Open the site in a browser and check with the host. Canonry keeps checking and sends health.recovered when it answers again.",
87206
+ remediation: "Open the site in a browser and check with the host. Canonry keeps checking and sends a recovery alert when it answers again.",
87135
87207
  details: { url, finalUrl: result.finalUrl, httpStatus: result.httpStatus, reason: result.reason, attempts: result.attempts, durationMs: result.durationMs }
87136
87208
  };
87137
87209
  }
@@ -87391,6 +87463,7 @@ function gradeSyncFailures(ctx, spec) {
87391
87463
  return {
87392
87464
  status: CheckStatuses.fail,
87393
87465
  code: code("repeated-failures"),
87466
+ urgent: true,
87394
87467
  summary: `The last ${state.consecutiveFailures} ${spec.label} syncs failed (last success: ${lastSuccessText}). Latest error: ${shownError}`,
87395
87468
  remediation: `Fix the cause the latest error names (DNS or network filtering of the API host, credentials, or account access), then run \`${spec.syncCommand(project.name)}\`.`,
87396
87469
  details
@@ -87417,7 +87490,7 @@ var INTEGRATION_SYNC_CHECKS = SPECS.map((spec) => ({
87417
87490
  var API_HOST_TABLE = {
87418
87491
  gsc: [new URL(GSC_API_BASE).hostname, new URL(URL_INSPECTION_API).hostname, new URL(GOOGLE_TOKEN_URL).hostname],
87419
87492
  ga: [new URL(GA4_DATA_API_BASE).hostname, new URL(GA4_ADMIN_API_BASE).hostname, new URL(GOOGLE_TOKEN_URL).hostname],
87420
- gbp: [new URL(GBP_ACCOUNT_MANAGEMENT_BASE).hostname, new URL(GBP_BUSINESS_INFO_BASE).hostname, new URL(GBP_PERFORMANCE_BASE).hostname, new URL(GBP_LEGACY_V4_BASE).hostname, new URL(GBP_LODGING_BASE).hostname, new URL(GOOGLE_TOKEN_URL).hostname],
87493
+ gbp: [new URL(GBP_ACCOUNT_MANAGEMENT_BASE).hostname, new URL(GBP_BUSINESS_INFO_BASE).hostname, new URL(GBP_PLACE_ACTIONS_BASE).hostname, new URL(GBP_PERFORMANCE_BASE).hostname, new URL(GBP_LEGACY_V4_BASE).hostname, new URL(GBP_LODGING_BASE).hostname, new URL(GOOGLE_TOKEN_URL).hostname],
87421
87494
  "google-ads": ["googleads.googleapis.com", "oauth2.googleapis.com"],
87422
87495
  gtm: ["tagmanager.googleapis.com", "oauth2.googleapis.com"],
87423
87496
  bing: [new URL(BING_WMT_API_BASE).hostname],
@@ -89641,7 +89714,7 @@ async function runChecks(ctx, checks, options = {}) {
89641
89714
  // An advisory that cannot run is still only an advisory: it must not
89642
89715
  // fail the doctor (and its exit code) the way a broken health check does.
89643
89716
  status: definition2.notificationPolicy === CheckNotificationPolicies.silent ? CheckStatuses.warn : CheckStatuses.fail,
89644
- code: `${definition2.id}.runtime-error`,
89717
+ code: `${definition2.id}${CHECK_RUNTIME_ERROR_SUFFIX}`,
89645
89718
  summary: `Check threw an unexpected error: ${message}`,
89646
89719
  remediation: null,
89647
89720
  details: { error: message }
@@ -89655,6 +89728,7 @@ async function runChecks(ctx, checks, options = {}) {
89655
89728
  status: output.status,
89656
89729
  ...definition2.notificationPolicy ? { notificationPolicy: definition2.notificationPolicy } : {},
89657
89730
  code: output.code,
89731
+ ...output.urgent ? { urgent: true } : {},
89658
89732
  summary: output.summary,
89659
89733
  remediation: output.remediation ?? null,
89660
89734
  details: output.details,
@@ -89674,7 +89748,7 @@ async function runChecks(ctx, checks, options = {}) {
89674
89748
  };
89675
89749
  }
89676
89750
  function threw(definition2, result) {
89677
- return result.code === `${definition2.id}.runtime-error`;
89751
+ return result.code === `${definition2.id}${CHECK_RUNTIME_ERROR_SUFFIX}`;
89678
89752
  }
89679
89753
  function namesCause(definition2, result) {
89680
89754
  return result.status === CheckStatuses.fail && !threw(definition2, result) && !result.code.endsWith(UNREACHABLE_CODE_SUFFIX);
@@ -3,10 +3,10 @@ import {
3
3
  buildCliCatalog,
4
4
  printCliCatalog,
5
5
  renderTopLevelHelp
6
- } from "./chunk-45Z5RJZW.js";
7
- import "./chunk-3JVF3ULD.js";
6
+ } from "./chunk-KMMOYVAO.js";
7
+ import "./chunk-KZS5N3JH.js";
8
8
  import "./chunk-HGMYEDAQ.js";
9
- import "./chunk-GZ2KIONF.js";
9
+ import "./chunk-6333IHPS.js";
10
10
  export {
11
11
  CLI_ROOT_SUMMARIES,
12
12
  buildCliCatalog,
@@ -0,0 +1,15 @@
1
+ import {
2
+ REGISTERED_CLI_COMMANDS
3
+ } from "./chunk-PIL3NHER.js";
4
+ import "./chunk-GCBMBG2Y.js";
5
+ import "./chunk-5A57TIOK.js";
6
+ import "./chunk-KZS5N3JH.js";
7
+ import "./chunk-RB2F4D3Z.js";
8
+ import "./chunk-EJTCZGU3.js";
9
+ import "./chunk-E7BG7QGP.js";
10
+ import "./chunk-HGMYEDAQ.js";
11
+ import "./chunk-XFBY4DJV.js";
12
+ import "./chunk-6333IHPS.js";
13
+ export {
14
+ REGISTERED_CLI_COMMANDS
15
+ };
package/dist/cli.js CHANGED
@@ -2,18 +2,18 @@
2
2
  import {
3
3
  autoSyncSkills,
4
4
  formatAutoSyncNotice
5
- } from "./chunk-SW54HXSZ.js";
5
+ } from "./chunk-55QNMM7V.js";
6
6
  import {
7
7
  accessFilterFromArgs,
8
8
  dispatchRegisteredCommand,
9
9
  printCliCatalog
10
- } from "./chunk-45Z5RJZW.js";
10
+ } from "./chunk-KMMOYVAO.js";
11
11
  import {
12
12
  REGISTERED_CLI_COMMANDS,
13
13
  buildSetupState,
14
14
  consumePendingServeHandoff,
15
15
  serveCommand
16
- } from "./chunk-57MGI2UT.js";
16
+ } from "./chunk-PIL3NHER.js";
17
17
  import {
18
18
  checkLatestVersionForCli,
19
19
  cliRuntimeContext,
@@ -27,14 +27,14 @@ import {
27
27
  showFirstRunNotice,
28
28
  trackCliCommandFinished,
29
29
  trackEvent
30
- } from "./chunk-LK7O7RM6.js";
31
- import "./chunk-5LY7EG4U.js";
30
+ } from "./chunk-GCBMBG2Y.js";
31
+ import "./chunk-5A57TIOK.js";
32
32
  import {
33
33
  resolveCliAccess
34
- } from "./chunk-3JVF3ULD.js";
34
+ } from "./chunk-KZS5N3JH.js";
35
35
  import "./chunk-RB2F4D3Z.js";
36
- import "./chunk-JVBI6VBT.js";
37
- import "./chunk-MPWBFKGK.js";
36
+ import "./chunk-EJTCZGU3.js";
37
+ import "./chunk-E7BG7QGP.js";
38
38
  import {
39
39
  CliError,
40
40
  EXIT_SYSTEM_ERROR,
@@ -42,10 +42,10 @@ import {
42
42
  printCliError,
43
43
  usageError
44
44
  } from "./chunk-HGMYEDAQ.js";
45
- import "./chunk-G47XJVAS.js";
45
+ import "./chunk-XFBY4DJV.js";
46
46
  import {
47
47
  OperationAccesses
48
- } from "./chunk-GZ2KIONF.js";
48
+ } from "./chunk-6333IHPS.js";
49
49
 
50
50
  // src/cli.ts
51
51
  import { pathToFileURL } from "url";
@@ -5,11 +5,11 @@ import {
5
5
  computeFactorAverages,
6
6
  layoutSiteCrawlGraphInput,
7
7
  persistSiteCrawlGraphLayout
8
- } from "./chunk-JVBI6VBT.js";
8
+ } from "./chunk-EJTCZGU3.js";
9
9
  import {
10
10
  PACKAGE_VERSION,
11
11
  canonryMcpTools
12
- } from "./chunk-MPWBFKGK.js";
12
+ } from "./chunk-E7BG7QGP.js";
13
13
  import "./chunk-HGMYEDAQ.js";
14
14
  import {
15
15
  HISTORY_WINDOW_RUNS,
@@ -86,7 +86,7 @@ import {
86
86
  siteCrawlPages,
87
87
  siteCrawlSnapshots,
88
88
  trafficSources
89
- } from "./chunk-G47XJVAS.js";
89
+ } from "./chunk-XFBY4DJV.js";
90
90
  import {
91
91
  RunKinds,
92
92
  SiteCrawlFetchStates,
@@ -116,7 +116,7 @@ import {
116
116
  roundPreservingTotal,
117
117
  siteAuditPageFactorSchema,
118
118
  wilsonInterval
119
- } from "./chunk-GZ2KIONF.js";
119
+ } from "./chunk-6333IHPS.js";
120
120
 
121
121
  // src/demo-server.ts
122
122
  import { dirname, join as join2 } from "path";
@@ -1882,7 +1882,7 @@ function harborDraft(plan) {
1882
1882
  label: target.label,
1883
1883
  status: "included",
1884
1884
  aliases: target.aliases,
1885
- urlMatchers: target.urlMatchers.map((matcher) => matcher.kind === "prefix" ? `https://${matcher.host}${matcher.pathPrefix}/*` : matcher.kind === "host" ? matcher.host : matcher.url),
1885
+ urlMatchers: target.urlMatchers.map((matcher) => matcher.kind === "prefix" ? `https://${matcher.host}${matcher.pathPrefix === "/" ? "" : matcher.pathPrefix}/*` : matcher.kind === "host" ? matcher.host : matcher.url),
1886
1886
  source: "sitemap",
1887
1887
  discoveredUrl: `https://${target.urlMatchers[0].kind === "prefix" ? target.urlMatchers[0].host + target.urlMatchers[0].pathPrefix : "harbor-resorts.example"}`,
1888
1888
  discoveryIdentity: target.discoveryIdentity ?? void 0
package/dist/index.js CHANGED
@@ -3,15 +3,15 @@ import {
3
3
  createGoogleMarketingCredentialStore,
4
4
  createGoogleMarketingRuntime,
5
5
  createServer
6
- } from "./chunk-LK7O7RM6.js";
6
+ } from "./chunk-GCBMBG2Y.js";
7
7
  import {
8
8
  loadConfig
9
- } from "./chunk-5LY7EG4U.js";
10
- import "./chunk-JVBI6VBT.js";
11
- import "./chunk-MPWBFKGK.js";
9
+ } from "./chunk-5A57TIOK.js";
10
+ import "./chunk-EJTCZGU3.js";
11
+ import "./chunk-E7BG7QGP.js";
12
12
  import "./chunk-HGMYEDAQ.js";
13
- import "./chunk-G47XJVAS.js";
14
- import "./chunk-GZ2KIONF.js";
13
+ import "./chunk-XFBY4DJV.js";
14
+ import "./chunk-6333IHPS.js";
15
15
  export {
16
16
  GoogleMarketingRuntimeError,
17
17
  createGoogleMarketingCredentialStore,
@@ -1,8 +1,8 @@
1
1
  import {
2
2
  HISTORY_WINDOW_RUNS,
3
3
  IntelligenceService
4
- } from "./chunk-G47XJVAS.js";
5
- import "./chunk-GZ2KIONF.js";
4
+ } from "./chunk-XFBY4DJV.js";
5
+ import "./chunk-6333IHPS.js";
6
6
  export {
7
7
  HISTORY_WINDOW_RUNS,
8
8
  IntelligenceService
package/dist/mcp.js CHANGED
@@ -1,16 +1,16 @@
1
1
  import {
2
2
  autoSyncSkills
3
- } from "./chunk-SW54HXSZ.js";
3
+ } from "./chunk-55QNMM7V.js";
4
4
  import {
5
5
  createApiClient,
6
6
  createCanonryMcpServer
7
- } from "./chunk-5LY7EG4U.js";
8
- import "./chunk-MPWBFKGK.js";
7
+ } from "./chunk-5A57TIOK.js";
8
+ import "./chunk-E7BG7QGP.js";
9
9
  import "./chunk-HGMYEDAQ.js";
10
10
  import {
11
11
  isReadOnlyKey,
12
12
  updateCheckEnvOptOut
13
- } from "./chunk-GZ2KIONF.js";
13
+ } from "./chunk-6333IHPS.js";
14
14
 
15
15
  // src/mcp/cli.ts
16
16
  import { randomUUID } from "crypto";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@canonry/canonry",
3
- "version": "7.44.1",
3
+ "version": "7.45.1",
4
4
  "type": "module",
5
5
  "description": "Self-hosted AI visibility (AEO) platform: track how ChatGPT, Claude, Gemini, and Perplexity cite your domain, join it with Search Console, GA4, server-side traffic, and paid media, and fix what you find through agent tools (CLI, REST, MCP). Local SQLite.",
6
6
  "keywords": [
@@ -85,34 +85,34 @@
85
85
  "@types/node-cron": "^3.0.11",
86
86
  "tsup": "^8.5.1",
87
87
  "tsx": "^4.19.0",
88
- "@ainyc/canonry-api-client": "0.0.0",
89
88
  "@ainyc/canonry-web": "0.0.0",
90
89
  "@ainyc/canonry-api-routes": "0.0.0",
90
+ "@ainyc/canonry-api-client": "0.0.0",
91
91
  "@ainyc/canonry-config": "0.0.0",
92
- "@ainyc/canonry-db": "0.0.0",
93
92
  "@ainyc/canonry-contracts": "0.0.0",
94
- "@ainyc/canonry-integration-bing": "0.0.0",
93
+ "@ainyc/canonry-db": "0.0.0",
95
94
  "@ainyc/canonry-integration-cloud-run": "0.0.0",
96
- "@ainyc/canonry-integration-cloudflare-queue": "0.0.0",
95
+ "@ainyc/canonry-integration-bing": "0.0.0",
97
96
  "@ainyc/canonry-integration-cloudflare-worker": "0.0.0",
97
+ "@ainyc/canonry-integration-cloudflare-queue": "0.0.0",
98
+ "@ainyc/canonry-integration-commoncrawl": "0.0.0",
98
99
  "@ainyc/canonry-integration-google": "0.0.0",
99
100
  "@ainyc/canonry-integration-google-business-profile": "0.0.0",
100
- "@ainyc/canonry-integration-google-ads": "0.0.0",
101
- "@ainyc/canonry-integration-commoncrawl": "0.0.0",
102
- "@ainyc/canonry-integration-google-places": "0.0.0",
103
101
  "@ainyc/canonry-integration-google-tag-manager": "0.0.0",
102
+ "@ainyc/canonry-integration-google-ads": "0.0.0",
104
103
  "@ainyc/canonry-integration-openai-ads": "0.0.0",
104
+ "@ainyc/canonry-integration-traffic": "0.0.0",
105
105
  "@ainyc/canonry-integration-wordpress": "0.0.0",
106
+ "@ainyc/canonry-integration-google-places": "0.0.0",
106
107
  "@ainyc/canonry-intelligence": "0.0.0",
107
- "@ainyc/canonry-provider-cdp": "0.0.0",
108
- "@ainyc/canonry-integration-traffic": "0.0.0",
109
108
  "@ainyc/canonry-provider-claude": "0.0.0",
109
+ "@ainyc/canonry-provider-cdp": "0.0.0",
110
110
  "@ainyc/canonry-provider-gemini": "0.0.0",
111
111
  "@ainyc/canonry-provider-local": "0.0.0",
112
112
  "@ainyc/canonry-provider-muse": "0.0.0",
113
- "@ainyc/canonry-provider-perplexity": "0.0.0",
113
+ "@ainyc/canonry-provider-openai": "0.0.0",
114
114
  "@ainyc/canonry-integration-typesafe": "0.0.0",
115
- "@ainyc/canonry-provider-openai": "0.0.0"
115
+ "@ainyc/canonry-provider-perplexity": "0.0.0"
116
116
  },
117
117
  "scripts": {
118
118
  "build": "pnpm run build:cli && pnpm run build:web",
@@ -1,15 +0,0 @@
1
- import {
2
- REGISTERED_CLI_COMMANDS
3
- } from "./chunk-57MGI2UT.js";
4
- import "./chunk-LK7O7RM6.js";
5
- import "./chunk-5LY7EG4U.js";
6
- import "./chunk-3JVF3ULD.js";
7
- import "./chunk-RB2F4D3Z.js";
8
- import "./chunk-JVBI6VBT.js";
9
- import "./chunk-MPWBFKGK.js";
10
- import "./chunk-HGMYEDAQ.js";
11
- import "./chunk-G47XJVAS.js";
12
- import "./chunk-GZ2KIONF.js";
13
- export {
14
- REGISTERED_CLI_COMMANDS
15
- };