@canonry/canonry 4.147.0 → 4.147.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 (27) hide show
  1. package/assets/assets/{AuditHistoryPanel-DiQ0Ynw5.js → AuditHistoryPanel-BbEZ_0W9.js} +1 -1
  2. package/assets/assets/{BacklinksPage-DLUQuPE_.js → BacklinksPage-B72RKxC-.js} +1 -1
  3. package/assets/assets/{ChartPrimitives-BoEy1qo7.js → ChartPrimitives-Cf-jQ3c8.js} +1 -1
  4. package/assets/assets/{HistoryPage-mYR2vk8n.js → HistoryPage-C2U1kxKw.js} +1 -1
  5. package/assets/assets/{MeasurementPropertyPage-BocyGHJN.js → MeasurementPropertyPage-ltcSZ0tw.js} +1 -1
  6. package/assets/assets/ProjectPage-ZcGjsDlb.js +12 -0
  7. package/assets/assets/{RunRow-Ct-A6H9e.js → RunRow-DxO-zxCm.js} +1 -1
  8. package/assets/assets/{RunsPage-CsDtq0Qw.js → RunsPage-B1ON2nQC.js} +1 -1
  9. package/assets/assets/{SettingsPage-BXwFGc1P.js → SettingsPage-Cp0bHFHk.js} +1 -1
  10. package/assets/assets/{TrafficPage-B2omyoI8.js → TrafficPage-QzitDjhV.js} +1 -1
  11. package/assets/assets/{TrafficSourceDetailPage-CoEqc6OJ.js → TrafficSourceDetailPage-BjfFyG2y.js} +1 -1
  12. package/assets/assets/{arrow-left-Dh0vsQxe.js → arrow-left-DJ8ZwUlj.js} +1 -1
  13. package/assets/assets/{extract-error-message-DvWJ0xRn.js → extract-error-message-CX8ZNJ8S.js} +1 -1
  14. package/assets/assets/{index-CXe6S1ey.css → index-D5NO3NEG.css} +1 -1
  15. package/assets/assets/{index-FE8JPHmT.js → index-DF8X6nM0.js} +73 -73
  16. package/assets/assets/{trash-2-D1_8ZseY.js → trash-2-UHAxuTT7.js} +1 -1
  17. package/assets/assets/{v2-overview-adapter-owDeFdUc.js → v2-overview-adapter-BHmxTmCf.js} +1 -1
  18. package/assets/index.html +2 -2
  19. package/dist/{chunk-4BL24FQA.js → chunk-2NTWZHNF.js} +352 -345
  20. package/dist/{chunk-ZDYS24LW.js → chunk-GNKVF6TZ.js} +6 -3
  21. package/dist/{chunk-DRDNHYIF.js → chunk-ZRUNFIGA.js} +61 -15
  22. package/dist/cli.js +199 -3
  23. package/dist/index.js +3 -3
  24. package/dist/{intelligence-service-7CGZ537D.js → intelligence-service-2E5YAXI3.js} +1 -1
  25. package/dist/mcp.js +1 -1
  26. package/package.json +7 -7
  27. package/assets/assets/ProjectPage-Q5wQ7nSW.js +0 -12
@@ -10,7 +10,7 @@ import {
10
10
  loadConfig,
11
11
  loadConfigRaw,
12
12
  saveConfigPatch
13
- } from "./chunk-4BL24FQA.js";
13
+ } from "./chunk-2NTWZHNF.js";
14
14
  import {
15
15
  CC_CACHE_DIR,
16
16
  DUCKDB_SPEC,
@@ -126,7 +126,7 @@ import {
126
126
  siteAuditSnapshots,
127
127
  toAlertView,
128
128
  usageCounters
129
- } from "./chunk-DRDNHYIF.js";
129
+ } from "./chunk-ZRUNFIGA.js";
130
130
  import {
131
131
  AGENT_MEMORY_VALUE_MAX_BYTES,
132
132
  AGENT_PROVIDER_IDS,
@@ -7420,7 +7420,7 @@ function readStoredGroundingSources(rawResponse) {
7420
7420
  return result;
7421
7421
  }
7422
7422
  async function backfillInsightsCommand(project, opts) {
7423
- const { IntelligenceService: IntelligenceService2 } = await import("./intelligence-service-7CGZ537D.js");
7423
+ const { IntelligenceService: IntelligenceService2 } = await import("./intelligence-service-2E5YAXI3.js");
7424
7424
  const config = loadConfig();
7425
7425
  const db = createClient(config.database);
7426
7426
  migrate(db);
@@ -13885,6 +13885,9 @@ async function createServer(opts) {
13885
13885
  if (!dashboardShowUpdateNotification) {
13886
13886
  dashboardConfig.showUpdateNotification = false;
13887
13887
  }
13888
+ if (!agentEnabled) {
13889
+ dashboardConfig.showAgentBar = false;
13890
+ }
13888
13891
  if (Object.keys(dashboardConfig).length > 0) {
13889
13892
  clientConfig.dashboard = dashboardConfig;
13890
13893
  }
@@ -5037,6 +5037,20 @@ var MIGRATION_VERSIONS = [
5037
5037
  `CREATE INDEX IF NOT EXISTS idx_measurement_operation_receipts_expires
5038
5038
  ON measurement_operation_receipts(expires_at)`
5039
5039
  ]
5040
+ },
5041
+ {
5042
+ version: 124,
5043
+ name: "measurement-foundation-named-indexes",
5044
+ statements: [
5045
+ `CREATE UNIQUE INDEX IF NOT EXISTS idx_measurement_plan_versions_project_revision
5046
+ ON measurement_plan_versions(project_id, revision)`,
5047
+ `CREATE UNIQUE INDEX IF NOT EXISTS idx_measurement_plan_versions_project_id
5048
+ ON measurement_plan_versions(project_id, id)`,
5049
+ `CREATE UNIQUE INDEX IF NOT EXISTS idx_measurement_segments_project_key
5050
+ ON measurement_segments(project_id, stable_key)`,
5051
+ `CREATE UNIQUE INDEX IF NOT EXISTS idx_measurement_segments_project_id
5052
+ ON measurement_segments(project_id, id)`
5053
+ ]
5040
5054
  }
5041
5055
  ];
5042
5056
  function addRunsMeasurementPlanVersionForeignKey(tx) {
@@ -33795,7 +33809,8 @@ async function exchangeCode(clientId, clientSecret, code, redirectUri) {
33795
33809
  detail += detail ? `: ${sanitized}` : sanitized;
33796
33810
  }
33797
33811
  } catch {
33798
- detail = body.length <= 120 ? body : `${body.slice(0, 120)}...`;
33812
+ const truncated = body.length <= 120 ? body : `${body.slice(0, 120)}...`;
33813
+ detail = truncated.replace(new RegExp(escapeRegExp(clientId), "g"), "***").replace(new RegExp(escapeRegExp(clientSecret), "g"), "***").replace(new RegExp(escapeRegExp(code), "g"), "***");
33799
33814
  }
33800
33815
  throw new GoogleAuthError(`Token exchange failed (${res.status}): ${detail}`);
33801
33816
  }
@@ -33833,7 +33848,8 @@ async function refreshAccessToken(clientId, clientSecret, currentRefreshToken) {
33833
33848
  detail += detail ? `: ${sanitized}` : sanitized;
33834
33849
  }
33835
33850
  } catch {
33836
- detail = body.length <= 120 ? body : `${body.slice(0, 120)}...`;
33851
+ const truncated = body.length <= 120 ? body : `${body.slice(0, 120)}...`;
33852
+ detail = truncated.replace(new RegExp(escapeRegExp(clientId), "g"), "***").replace(new RegExp(escapeRegExp(clientSecret), "g"), "***").replace(new RegExp(escapeRegExp(currentRefreshToken), "g"), "***");
33837
33853
  }
33838
33854
  throw new GoogleAuthError(`Token refresh failed (${res.status}): ${detail}`);
33839
33855
  }
@@ -33923,6 +33939,9 @@ function gscClientLog(level, action, ctx) {
33923
33939
  const stream = level === "error" ? process.stderr : process.stdout;
33924
33940
  stream.write(JSON.stringify(entry) + "\n");
33925
33941
  }
33942
+ function escapeRegExp2(str) {
33943
+ return str.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
33944
+ }
33926
33945
  async function gscFetchResponse(accessToken, url, opts) {
33927
33946
  const method = opts?.method ?? "GET";
33928
33947
  const headers = {
@@ -33947,7 +33966,11 @@ async function gscFetchResponse(accessToken, url, opts) {
33947
33966
  const body = await res.text();
33948
33967
  gscClientLog("error", "http.error", { url, method, httpStatus: res.status });
33949
33968
  const detail = body.length <= 500 ? body : `${body.slice(0, 500)}... [truncated]`;
33950
- throw new GoogleApiError(`GSC API error (${res.status}): ${detail}`, res.status);
33969
+ let sanitizedDetail = detail;
33970
+ if (accessToken) {
33971
+ sanitizedDetail = sanitizedDetail.replace(new RegExp(escapeRegExp2(accessToken), "g"), "***");
33972
+ }
33973
+ throw new GoogleApiError(`GSC API error (${res.status}): ${sanitizedDetail}`, res.status);
33951
33974
  }
33952
33975
  return res;
33953
33976
  }
@@ -34206,13 +34229,13 @@ async function getAccessToken(clientEmail, privateKey) {
34206
34229
  const body = await res.text().catch(() => "");
34207
34230
  ga4Log("error", "token.failed", { httpStatus: res.status });
34208
34231
  const detail = body.length <= 200 ? body : `${body.slice(0, 200)}... [truncated]`;
34209
- const sanitizedDetail = detail.replace(new RegExp(escapeRegExp2(clientEmail), "g"), "***").replace(new RegExp(escapeRegExp2(privateKey.slice(0, 32)), "g"), "***");
34232
+ const sanitizedDetail = detail.replace(new RegExp(escapeRegExp3(clientEmail), "g"), "***").replace(new RegExp(escapeRegExp3(privateKey.slice(0, 32)), "g"), "***");
34210
34233
  throw new GA4ApiError(`Failed to get access token: ${sanitizedDetail}`, res.status);
34211
34234
  }
34212
34235
  const data = await res.json();
34213
34236
  return data.access_token;
34214
34237
  }
34215
- function escapeRegExp2(str) {
34238
+ function escapeRegExp3(str) {
34216
34239
  return str.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
34217
34240
  }
34218
34241
  var gaInFlight = 0;
@@ -34315,9 +34338,13 @@ async function runReport(accessToken, propertyId, request) {
34315
34338
  } catch {
34316
34339
  if (body.length < 200) detail = ` ${body}`;
34317
34340
  }
34341
+ let sanitizedDetail = detail;
34342
+ if (accessToken) {
34343
+ sanitizedDetail = sanitizedDetail.replace(new RegExp(escapeRegExp3(accessToken), "g"), "***");
34344
+ }
34318
34345
  ga4Log("error", "report.auth-failed", { propertyId, httpStatus: res.status });
34319
34346
  throw new GA4ApiError(
34320
- `GA4 API authentication failed \u2014 check service account permissions.${detail}`,
34347
+ `GA4 API authentication failed \u2014 check service account permissions.${sanitizedDetail}`,
34321
34348
  res.status
34322
34349
  );
34323
34350
  }
@@ -34331,7 +34358,11 @@ async function runReport(accessToken, propertyId, request) {
34331
34358
  const retryAfterSeconds = res.status >= 500 ? parseRetryAfter(res.headers.get("retry-after")) : void 0;
34332
34359
  ga4Log("error", "report.error", { propertyId, httpStatus: res.status, retryAfterSeconds });
34333
34360
  const detail = body.length <= 500 ? body : `${body.slice(0, 500)}... [truncated]`;
34334
- throw new GA4ApiError(`GA4 API error (${res.status}): ${detail}`, res.status, retryAfterSeconds);
34361
+ let sanitizedDetail = detail;
34362
+ if (accessToken) {
34363
+ sanitizedDetail = sanitizedDetail.replace(new RegExp(escapeRegExp3(accessToken), "g"), "***");
34364
+ }
34365
+ throw new GA4ApiError(`GA4 API error (${res.status}): ${sanitizedDetail}`, res.status, retryAfterSeconds);
34335
34366
  }
34336
34367
  return await res.json();
34337
34368
  }, "report"));
@@ -34351,8 +34382,12 @@ async function batchRunReports(accessToken, propertyId, requests) {
34351
34382
  if (res.status === 401 || res.status === 403) {
34352
34383
  const body = await res.text().catch(() => "");
34353
34384
  ga4Log("error", "batch-report.auth-failed", { propertyId, httpStatus: res.status });
34385
+ let sanitizedDetail = body;
34386
+ if (accessToken) {
34387
+ sanitizedDetail = sanitizedDetail.replace(new RegExp(escapeRegExp3(accessToken), "g"), "***");
34388
+ }
34354
34389
  throw new GA4ApiError(
34355
- `GA4 API authentication failed \u2014 check service account permissions. ${body}`,
34390
+ `GA4 API authentication failed \u2014 check service account permissions. ${sanitizedDetail}`,
34356
34391
  res.status
34357
34392
  );
34358
34393
  }
@@ -34366,7 +34401,11 @@ async function batchRunReports(accessToken, propertyId, requests) {
34366
34401
  const retryAfterSeconds = res.status >= 500 ? parseRetryAfter(res.headers.get("retry-after")) : void 0;
34367
34402
  ga4Log("error", "batch-report.error", { propertyId, httpStatus: res.status, retryAfterSeconds });
34368
34403
  const detail = body.length <= 500 ? body : `${body.slice(0, 500)}... [truncated]`;
34369
- throw new GA4ApiError(`GA4 API error (${res.status}): ${detail}`, res.status, retryAfterSeconds);
34404
+ let sanitizedDetail = detail;
34405
+ if (accessToken) {
34406
+ sanitizedDetail = sanitizedDetail.replace(new RegExp(escapeRegExp3(accessToken), "g"), "***");
34407
+ }
34408
+ throw new GA4ApiError(`GA4 API error (${res.status}): ${sanitizedDetail}`, res.status, retryAfterSeconds);
34370
34409
  }
34371
34410
  const data = await res.json();
34372
34411
  return data.reports;
@@ -41701,7 +41740,7 @@ function bingClientLog(level, action, ctx) {
41701
41740
  const stream = level === "error" ? process.stderr : process.stdout;
41702
41741
  stream.write(JSON.stringify(entry) + "\n");
41703
41742
  }
41704
- function escapeRegExp3(str) {
41743
+ function escapeRegExp4(str) {
41705
41744
  return str.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
41706
41745
  }
41707
41746
  async function bingFetch(apiKey, endpoint, opts) {
@@ -41729,7 +41768,7 @@ async function bingFetch(apiKey, endpoint, opts) {
41729
41768
  const body = await res.text();
41730
41769
  bingClientLog("error", "http.error", { endpoint, method, httpStatus: res.status });
41731
41770
  let detail = body.length <= 500 ? body : `${body.slice(0, 500)}... [truncated]`;
41732
- detail = detail.replace(new RegExp(escapeRegExp3(apiKey), "g"), "***");
41771
+ detail = detail.replace(new RegExp(escapeRegExp4(apiKey), "g"), "***");
41733
41772
  throw new BingApiError(`Bing API error (${res.status}): ${detail}`, res.status);
41734
41773
  }
41735
41774
  const text2 = await res.text();
@@ -43938,7 +43977,14 @@ async function fetchJson(connection, siteUrl, path8, init) {
43938
43977
  }
43939
43978
  if (!res.ok) {
43940
43979
  const text2 = await res.text().catch(() => "");
43941
- throw new WordpressApiError("UPSTREAM_ERROR", `WordPress API error (${res.status}): ${text2 || res.statusText}`, res.status);
43980
+ let detail = text2 || res.statusText;
43981
+ if (connection.appPassword) {
43982
+ detail = detail.replace(new RegExp(escapeRegExp5(connection.appPassword), "g"), "***");
43983
+ }
43984
+ if (connection.username) {
43985
+ detail = detail.replace(new RegExp(escapeRegExp5(connection.username), "g"), "***");
43986
+ }
43987
+ throw new WordpressApiError("UPSTREAM_ERROR", `WordPress API error (${res.status}): ${detail}`, res.status);
43942
43988
  }
43943
43989
  return {
43944
43990
  body: await res.json(),
@@ -44431,12 +44477,12 @@ var CANONRY_SCHEMA_START = "<!-- canonry:schema:start -->";
44431
44477
  var CANONRY_SCHEMA_END = "<!-- canonry:schema:end -->";
44432
44478
  function stripCanonrySchema(content) {
44433
44479
  const regex = new RegExp(
44434
- `${escapeRegExp4(CANONRY_SCHEMA_START)}[\\s\\S]*?${escapeRegExp4(CANONRY_SCHEMA_END)}`,
44480
+ `${escapeRegExp5(CANONRY_SCHEMA_START)}[\\s\\S]*?${escapeRegExp5(CANONRY_SCHEMA_END)}`,
44435
44481
  "g"
44436
44482
  );
44437
44483
  return content.replace(regex, "").replace(/\n{3,}/g, "\n\n").trim();
44438
44484
  }
44439
- function escapeRegExp4(str) {
44485
+ function escapeRegExp5(str) {
44440
44486
  return str.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
44441
44487
  }
44442
44488
  function injectCanonrySchema(content, schemas) {
@@ -44543,7 +44589,7 @@ async function getSchemaStatus(connection, env) {
44543
44589
  const thirdPartySchemas = [];
44544
44590
  if (hasCanonryMarker) {
44545
44591
  const markerRegex = new RegExp(
44546
- `${escapeRegExp4(CANONRY_SCHEMA_START)}([\\s\\S]*?)${escapeRegExp4(CANONRY_SCHEMA_END)}`
44592
+ `${escapeRegExp5(CANONRY_SCHEMA_START)}([\\s\\S]*?)${escapeRegExp5(CANONRY_SCHEMA_END)}`
44547
44593
  );
44548
44594
  const match = markerRegex.exec(rawContent);
44549
44595
  if (match?.[1]) {
package/dist/cli.js CHANGED
@@ -30,7 +30,7 @@ import {
30
30
  showFirstRunNotice,
31
31
  trackCliCommandFinished,
32
32
  trackEvent
33
- } from "./chunk-ZDYS24LW.js";
33
+ } from "./chunk-GNKVF6TZ.js";
34
34
  import {
35
35
  CliError,
36
36
  EXIT_SYSTEM_ERROR,
@@ -43,12 +43,14 @@ import {
43
43
  isMachineFormat,
44
44
  loadConfig,
45
45
  loadConfigRaw,
46
+ measurementDraftOperationSchema,
46
47
  printCliError,
48
+ runMeasurementDraftAction,
47
49
  saveConfig,
48
50
  saveConfigPatch,
49
51
  systemError,
50
52
  usageError
51
- } from "./chunk-4BL24FQA.js";
53
+ } from "./chunk-2NTWZHNF.js";
52
54
  import {
53
55
  apiKeys,
54
56
  createClient,
@@ -56,7 +58,7 @@ import {
56
58
  projects,
57
59
  queries,
58
60
  renderReportHtml
59
- } from "./chunk-DRDNHYIF.js";
61
+ } from "./chunk-ZRUNFIGA.js";
60
62
  import {
61
63
  AdsDeliverySnapshotStatuses,
62
64
  AdsHistoricalCampaignRollupStatuses,
@@ -100,9 +102,21 @@ import {
100
102
  formatMicros,
101
103
  formatRatio,
102
104
  formatRunErrorOneLine,
105
+ measurementChangesQuerySchema,
106
+ measurementDataQualityQuerySchema,
103
107
  measurementDiscoveryRequestSchema,
104
108
  measurementDiscoveryRuleSchema,
109
+ measurementDraftCollectionQuerySchema,
110
+ measurementOverviewQuerySchema,
111
+ measurementPlanDeactivateRequestSchema,
105
112
  measurementPlanInputSchema,
113
+ measurementPortfolioSummaryQuerySchema,
114
+ measurementPropertyCompetitorsQuerySchema,
115
+ measurementPropertyQuestionsQuerySchema,
116
+ measurementQuerySetUpsertRequestSchema,
117
+ measurementQueryTemplateApplyRequestSchema,
118
+ measurementQueryTemplateUpsertRequestSchema,
119
+ measurementQuestionResultQuerySchema,
106
120
  normalizeProjectAliases,
107
121
  notificationEventSchema,
108
122
  providerQuotaPolicySchema,
@@ -15719,6 +15733,7 @@ Usage: ${usage}`, {
15719
15733
  import crypto3 from "crypto";
15720
15734
  import fs16 from "fs";
15721
15735
  import { parse } from "yaml";
15736
+ import { z as z2 } from "zod";
15722
15737
  function readPlan(source) {
15723
15738
  const content = source === "-" ? fs16.readFileSync(0, "utf8") : fs16.readFileSync(source, "utf8");
15724
15739
  const parsed = source.endsWith(".json") ? JSON.parse(content) : parse(content);
@@ -15729,6 +15744,171 @@ function readDiscoveryRule(source) {
15729
15744
  const parsed = source.endsWith(".json") ? JSON.parse(content) : parse(content);
15730
15745
  return measurementDiscoveryRuleSchema.parse(parsed);
15731
15746
  }
15747
+ var ADVANCED_MEASUREMENT_OPERATIONS = [
15748
+ "setup",
15749
+ "overview",
15750
+ "portfolio-summary",
15751
+ "property-questions",
15752
+ "question-result",
15753
+ "property-competitors",
15754
+ "changes",
15755
+ "data-quality",
15756
+ "draft",
15757
+ "draft-targets",
15758
+ "draft-assignments",
15759
+ "draft-groups",
15760
+ "draft-action",
15761
+ "deactivate",
15762
+ "query-sets",
15763
+ "query-set-get",
15764
+ "query-set-upsert",
15765
+ "query-set-delete",
15766
+ "query-templates",
15767
+ "query-template-upsert",
15768
+ "query-template-delete",
15769
+ "query-template-apply"
15770
+ ];
15771
+ var advancedIdempotencyKeySchema = z2.string().trim().min(1);
15772
+ var advancedResourceIdSchema = z2.string().trim().min(1);
15773
+ var advancedEmptyInputSchema = z2.object({}).strict();
15774
+ var advancedQuerySetInputSchema = z2.object({ setId: advancedResourceIdSchema }).strict();
15775
+ var advancedQuerySetUpsertInputSchema = advancedQuerySetInputSchema.extend({
15776
+ request: measurementQuerySetUpsertRequestSchema
15777
+ }).strict();
15778
+ var advancedQueryTemplateInputSchema = z2.object({ templateId: advancedResourceIdSchema }).strict();
15779
+ var advancedQueryTemplateUpsertInputSchema = advancedQueryTemplateInputSchema.extend({
15780
+ request: measurementQueryTemplateUpsertRequestSchema
15781
+ }).strict();
15782
+ var advancedQueryTemplateApplyInputSchema = advancedQueryTemplateInputSchema.extend({
15783
+ request: measurementQueryTemplateApplyRequestSchema,
15784
+ idempotencyKey: advancedIdempotencyKeySchema
15785
+ }).strict();
15786
+ var advancedDeactivateInputSchema = z2.object({
15787
+ request: measurementPlanDeactivateRequestSchema,
15788
+ idempotencyKey: advancedIdempotencyKeySchema
15789
+ }).strict();
15790
+ function readAdvancedMeasurementInput(source) {
15791
+ if (source === void 0) return {};
15792
+ const content = source === "-" ? fs16.readFileSync(0, "utf8") : fs16.readFileSync(source, "utf8");
15793
+ return JSON.parse(content);
15794
+ }
15795
+ var advancedMeasurementCollectionKeys = {
15796
+ "draft-targets": "items",
15797
+ "draft-assignments": "items",
15798
+ "draft-groups": "items",
15799
+ "query-sets": "querySets",
15800
+ "query-templates": "templates"
15801
+ };
15802
+ function isAdvancedMeasurementCollectionOperation(operation) {
15803
+ return operation === "draft-targets" || operation === "draft-assignments" || operation === "draft-groups" || operation === "query-sets" || operation === "query-templates";
15804
+ }
15805
+ function emitAdvancedMeasurementJsonl(operation, result) {
15806
+ if (!isAdvancedMeasurementCollectionOperation(operation) || typeof result !== "object" || result === null || Array.isArray(result)) return false;
15807
+ const collectionKey = advancedMeasurementCollectionKeys[operation];
15808
+ const envelope = result;
15809
+ const candidateRows = envelope[collectionKey];
15810
+ if (!Array.isArray(candidateRows)) return false;
15811
+ const context = {};
15812
+ for (const [key, value] of Object.entries(envelope)) {
15813
+ if (key !== collectionKey) context[key] = value;
15814
+ }
15815
+ emitJsonl([{ kind: "measurement-advanced-header", operation, ...context }]);
15816
+ emitJsonl(candidateRows.map((row) => row));
15817
+ return true;
15818
+ }
15819
+ async function runAdvancedMeasurementOperation(project, operation, source, format) {
15820
+ const input = readAdvancedMeasurementInput(source);
15821
+ const client = createApiClient();
15822
+ let result;
15823
+ switch (operation) {
15824
+ case "setup":
15825
+ advancedEmptyInputSchema.parse(input);
15826
+ result = await client.getMeasurementSetup(project);
15827
+ break;
15828
+ case "overview":
15829
+ result = await client.getMeasurementOverview(project, measurementOverviewQuerySchema.parse(input));
15830
+ break;
15831
+ case "portfolio-summary":
15832
+ result = await client.getMeasurementPortfolioSummary(project, measurementPortfolioSummaryQuerySchema.parse(input));
15833
+ break;
15834
+ case "property-questions":
15835
+ result = await client.getMeasurementPropertyQuestions(project, measurementPropertyQuestionsQuerySchema.parse(input));
15836
+ break;
15837
+ case "question-result":
15838
+ result = await client.getMeasurementQuestionResult(project, measurementQuestionResultQuerySchema.parse(input));
15839
+ break;
15840
+ case "property-competitors":
15841
+ result = await client.getMeasurementPropertyCompetitors(project, measurementPropertyCompetitorsQuerySchema.parse(input));
15842
+ break;
15843
+ case "changes":
15844
+ result = await client.getMeasurementChanges(project, measurementChangesQuerySchema.parse(input));
15845
+ break;
15846
+ case "data-quality":
15847
+ result = await client.getMeasurementDataQuality(project, measurementDataQualityQuerySchema.parse(input));
15848
+ break;
15849
+ case "draft":
15850
+ advancedEmptyInputSchema.parse(input);
15851
+ result = await client.getMeasurementPlanDraft(project);
15852
+ break;
15853
+ case "draft-targets":
15854
+ result = await client.getMeasurementDraftTargets(project, measurementDraftCollectionQuerySchema.parse(input));
15855
+ break;
15856
+ case "draft-assignments":
15857
+ result = await client.getMeasurementDraftAssignments(project, measurementDraftCollectionQuerySchema.parse(input));
15858
+ break;
15859
+ case "draft-groups":
15860
+ result = await client.getMeasurementDraftGroups(project, measurementDraftCollectionQuerySchema.parse(input));
15861
+ break;
15862
+ case "draft-action":
15863
+ result = await runMeasurementDraftAction(client, project, measurementDraftOperationSchema.parse(input));
15864
+ break;
15865
+ case "deactivate": {
15866
+ const parsed = advancedDeactivateInputSchema.parse(input);
15867
+ result = await client.deactivateMeasurementPlan(project, parsed.request, parsed.idempotencyKey);
15868
+ break;
15869
+ }
15870
+ case "query-sets":
15871
+ advancedEmptyInputSchema.parse(input);
15872
+ result = await client.listMeasurementQuerySets(project);
15873
+ break;
15874
+ case "query-set-get": {
15875
+ const parsed = advancedQuerySetInputSchema.parse(input);
15876
+ result = await client.getMeasurementQuerySet(project, parsed.setId);
15877
+ break;
15878
+ }
15879
+ case "query-set-upsert": {
15880
+ const parsed = advancedQuerySetUpsertInputSchema.parse(input);
15881
+ result = await client.upsertMeasurementQuerySet(project, parsed.setId, parsed.request);
15882
+ break;
15883
+ }
15884
+ case "query-set-delete": {
15885
+ const parsed = advancedQuerySetInputSchema.parse(input);
15886
+ result = await client.deleteMeasurementQuerySet(project, parsed.setId);
15887
+ break;
15888
+ }
15889
+ case "query-templates":
15890
+ advancedEmptyInputSchema.parse(input);
15891
+ result = await client.listMeasurementQueryTemplates(project);
15892
+ break;
15893
+ case "query-template-upsert": {
15894
+ const parsed = advancedQueryTemplateUpsertInputSchema.parse(input);
15895
+ result = await client.upsertMeasurementQueryTemplate(project, parsed.templateId, parsed.request);
15896
+ break;
15897
+ }
15898
+ case "query-template-delete": {
15899
+ const parsed = advancedQueryTemplateInputSchema.parse(input);
15900
+ result = await client.deleteMeasurementQueryTemplate(project, parsed.templateId);
15901
+ break;
15902
+ }
15903
+ case "query-template-apply": {
15904
+ const parsed = advancedQueryTemplateApplyInputSchema.parse(input);
15905
+ result = await client.applyMeasurementQueryTemplate(project, parsed.templateId, parsed.request, parsed.idempotencyKey);
15906
+ break;
15907
+ }
15908
+ }
15909
+ if (format === "jsonl" && emitAdvancedMeasurementJsonl(operation, result)) return;
15910
+ console.log(JSON.stringify(result ?? null, null, 2));
15911
+ }
15732
15912
  async function showMeasurementPlan(project, revision) {
15733
15913
  const client = createApiClient();
15734
15914
  console.log(JSON.stringify(revision === void 0 ? await client.getMeasurementPlan(project) : await client.getMeasurementPlanVersion(project, revision), null, 2));
@@ -16008,6 +16188,12 @@ Usage: ${usage}`);
16008
16188
  }
16009
16189
  return { project, options: { groupKeys, targetKeys, queryIds, allProperties } };
16010
16190
  }
16191
+ function advancedMeasurementOperation(value, usage) {
16192
+ const operation = ADVANCED_MEASUREMENT_OPERATIONS.find((candidate) => candidate === value);
16193
+ if (operation) return operation;
16194
+ throw usageError(`Error: unsupported Advanced Measurement operation: ${value ?? "(none)"}
16195
+ Usage: ${usage}`);
16196
+ }
16011
16197
  var MEASUREMENT_PLAN_CLI_COMMANDS = [
16012
16198
  { path: ["measurement-plan", "show"], usage: "canonry measurement-plan show <project> [--revision N] [--format json]", options: { revision: stringOption() }, run: async (input) => {
16013
16199
  const value = getString(input.values, "revision");
@@ -16028,6 +16214,16 @@ var MEASUREMENT_PLAN_CLI_COMMANDS = [
16028
16214
  if (!stableKey) throw usageError("stable segment key is required");
16029
16215
  return retireMeasurementPlanSegment(project, stableKey);
16030
16216
  } },
16217
+ {
16218
+ path: ["measurement-plan", "advanced"],
16219
+ usage: "canonry measurement-plan advanced <project> <operation> [<json|->] [--format json|jsonl]",
16220
+ run: (input) => {
16221
+ const usage = "canonry measurement-plan advanced <project> <operation> [<json|->] [--format json|jsonl]";
16222
+ const project = requireProject(input, "measurement-plan.advanced", usage);
16223
+ const operation = advancedMeasurementOperation(input.positionals[1], usage);
16224
+ return runAdvancedMeasurementOperation(project, operation, input.positionals[2], input.format);
16225
+ }
16226
+ },
16031
16227
  {
16032
16228
  path: ["measurement-plan", "assignments", "preview"],
16033
16229
  usage: "canonry measurement-plan assignments preview <project> [--group KEY ...] [--target-key KEY ... | --all-properties] --query-id ID [--query-id ID ...] [--format json]",
package/dist/index.js CHANGED
@@ -1,10 +1,10 @@
1
1
  import {
2
2
  createServer
3
- } from "./chunk-ZDYS24LW.js";
3
+ } from "./chunk-GNKVF6TZ.js";
4
4
  import {
5
5
  loadConfig
6
- } from "./chunk-4BL24FQA.js";
7
- import "./chunk-DRDNHYIF.js";
6
+ } from "./chunk-2NTWZHNF.js";
7
+ import "./chunk-ZRUNFIGA.js";
8
8
  import "./chunk-BVOU4UJM.js";
9
9
  export {
10
10
  createServer,
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  IntelligenceService
3
- } from "./chunk-DRDNHYIF.js";
3
+ } from "./chunk-ZRUNFIGA.js";
4
4
  import "./chunk-BVOU4UJM.js";
5
5
  export {
6
6
  IntelligenceService
package/dist/mcp.js CHANGED
@@ -3,7 +3,7 @@ import {
3
3
  PACKAGE_VERSION,
4
4
  canonryMcpTools,
5
5
  createApiClient
6
- } from "./chunk-4BL24FQA.js";
6
+ } from "./chunk-2NTWZHNF.js";
7
7
  import {
8
8
  isReadOnlyKey
9
9
  } from "./chunk-BVOU4UJM.js";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@canonry/canonry",
3
- "version": "4.147.0",
3
+ "version": "4.147.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",
@@ -68,25 +68,25 @@
68
68
  "tsx": "^4.19.0",
69
69
  "@ainyc/canonry-api-client": "0.0.0",
70
70
  "@ainyc/canonry-config": "0.0.0",
71
- "@ainyc/canonry-api-routes": "0.0.0",
72
- "@ainyc/canonry-db": "0.0.0",
73
71
  "@ainyc/canonry-contracts": "0.0.0",
72
+ "@ainyc/canonry-db": "0.0.0",
73
+ "@ainyc/canonry-api-routes": "0.0.0",
74
74
  "@ainyc/canonry-integration-bing": "0.0.0",
75
75
  "@ainyc/canonry-integration-openai-ads": "0.0.0",
76
76
  "@ainyc/canonry-integration-cloud-run": "0.0.0",
77
77
  "@ainyc/canonry-integration-google": "0.0.0",
78
- "@ainyc/canonry-integration-commoncrawl": "0.0.0",
79
78
  "@ainyc/canonry-integration-google-business-profile": "0.0.0",
80
79
  "@ainyc/canonry-integration-google-places": "0.0.0",
81
80
  "@ainyc/canonry-integration-traffic": "0.0.0",
82
- "@ainyc/canonry-integration-wordpress": "0.0.0",
83
81
  "@ainyc/canonry-intelligence": "0.0.0",
84
82
  "@ainyc/canonry-provider-cdp": "0.0.0",
83
+ "@ainyc/canonry-integration-commoncrawl": "0.0.0",
85
84
  "@ainyc/canonry-provider-claude": "0.0.0",
86
85
  "@ainyc/canonry-provider-gemini": "0.0.0",
87
86
  "@ainyc/canonry-provider-local": "0.0.0",
88
- "@ainyc/canonry-provider-openai": "0.0.0",
89
- "@ainyc/canonry-provider-perplexity": "0.0.0"
87
+ "@ainyc/canonry-integration-wordpress": "0.0.0",
88
+ "@ainyc/canonry-provider-perplexity": "0.0.0",
89
+ "@ainyc/canonry-provider-openai": "0.0.0"
90
90
  },
91
91
  "scripts": {
92
92
  "build": "tsx scripts/copy-agent-assets.ts && tsup && tsx build-web.ts",