@canonry/canonry 4.146.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.
- package/assets/assets/{AuditHistoryPanel-IDsSUFI3.js → AuditHistoryPanel-BbEZ_0W9.js} +1 -1
- package/assets/assets/{BacklinksPage-BswN-pyj.js → BacklinksPage-B72RKxC-.js} +1 -1
- package/assets/assets/{ChartPrimitives-CIe-R58_.js → ChartPrimitives-Cf-jQ3c8.js} +1 -1
- package/assets/assets/{HistoryPage-B18Jpq8c.js → HistoryPage-C2U1kxKw.js} +1 -1
- package/assets/assets/MeasurementPropertyPage-ltcSZ0tw.js +1 -0
- package/assets/assets/ProjectPage-ZcGjsDlb.js +12 -0
- package/assets/assets/{RunRow-3ZwTR4Bv.js → RunRow-DxO-zxCm.js} +1 -1
- package/assets/assets/{RunsPage-BCAJulR1.js → RunsPage-B1ON2nQC.js} +1 -1
- package/assets/assets/{SettingsPage-BT2_l0Do.js → SettingsPage-Cp0bHFHk.js} +1 -1
- package/assets/assets/{TrafficPage-Cux8rj5G.js → TrafficPage-QzitDjhV.js} +1 -1
- package/assets/assets/{TrafficSourceDetailPage-DI1Ad8KS.js → TrafficSourceDetailPage-BjfFyG2y.js} +1 -1
- package/assets/assets/{arrow-left-BMSx9HQB.js → arrow-left-DJ8ZwUlj.js} +1 -1
- package/assets/assets/extract-error-message-CX8ZNJ8S.js +1 -0
- package/assets/assets/{index-C6E5hp28.css → index-D5NO3NEG.css} +1 -1
- package/assets/assets/index-DF8X6nM0.js +213 -0
- package/assets/assets/{trash-2-CyoJtRAr.js → trash-2-UHAxuTT7.js} +1 -1
- package/assets/assets/{v2-overview-adapter-owDeFdUc.js → v2-overview-adapter-BHmxTmCf.js} +1 -1
- package/assets/index.html +2 -2
- package/dist/{chunk-UQOTEIA6.js → chunk-2NTWZHNF.js} +712 -330
- package/dist/{chunk-B5H55ZMA.js → chunk-BVOU4UJM.js} +3687 -3025
- package/dist/{chunk-Z7B6BRPP.js → chunk-GNKVF6TZ.js} +7 -4
- package/dist/{chunk-ED7C5TWT.js → chunk-ZRUNFIGA.js} +3818 -1439
- package/dist/cli.js +419 -15
- package/dist/index.js +4 -4
- package/dist/{intelligence-service-M5UNHF7X.js → intelligence-service-2E5YAXI3.js} +2 -2
- package/dist/mcp.js +5 -5
- package/package.json +12 -11
- package/assets/assets/MeasurementPropertyPage-CvmQeoo7.js +0 -1
- package/assets/assets/ProjectPage-BE1MUAB5.js +0 -11
- package/assets/assets/extract-error-message-B-9FdQh8.js +0 -1
- package/assets/assets/index-kOXUzdqD.js +0 -213
package/dist/cli.js
CHANGED
|
@@ -30,7 +30,7 @@ import {
|
|
|
30
30
|
showFirstRunNotice,
|
|
31
31
|
trackCliCommandFinished,
|
|
32
32
|
trackEvent
|
|
33
|
-
} from "./chunk-
|
|
33
|
+
} from "./chunk-GNKVF6TZ.js";
|
|
34
34
|
import {
|
|
35
35
|
CliError,
|
|
36
36
|
EXIT_SYSTEM_ERROR,
|
|
@@ -43,11 +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,
|
|
51
|
+
systemError,
|
|
49
52
|
usageError
|
|
50
|
-
} from "./chunk-
|
|
53
|
+
} from "./chunk-2NTWZHNF.js";
|
|
51
54
|
import {
|
|
52
55
|
apiKeys,
|
|
53
56
|
createClient,
|
|
@@ -55,7 +58,7 @@ import {
|
|
|
55
58
|
projects,
|
|
56
59
|
queries,
|
|
57
60
|
renderReportHtml
|
|
58
|
-
} from "./chunk-
|
|
61
|
+
} from "./chunk-ZRUNFIGA.js";
|
|
59
62
|
import {
|
|
60
63
|
AdsDeliverySnapshotStatuses,
|
|
61
64
|
AdsHistoricalCampaignRollupStatuses,
|
|
@@ -68,6 +71,7 @@ import {
|
|
|
68
71
|
CheckScopes,
|
|
69
72
|
CheckStatuses,
|
|
70
73
|
CitationStates,
|
|
74
|
+
MeasurementEvidenceShapes,
|
|
71
75
|
READ_ONLY_SCOPE,
|
|
72
76
|
REPORT_PERIOD_OPTIONS,
|
|
73
77
|
ResearchRunStatuses,
|
|
@@ -98,15 +102,27 @@ import {
|
|
|
98
102
|
formatMicros,
|
|
99
103
|
formatRatio,
|
|
100
104
|
formatRunErrorOneLine,
|
|
105
|
+
measurementChangesQuerySchema,
|
|
106
|
+
measurementDataQualityQuerySchema,
|
|
101
107
|
measurementDiscoveryRequestSchema,
|
|
102
108
|
measurementDiscoveryRuleSchema,
|
|
109
|
+
measurementDraftCollectionQuerySchema,
|
|
110
|
+
measurementOverviewQuerySchema,
|
|
111
|
+
measurementPlanDeactivateRequestSchema,
|
|
103
112
|
measurementPlanInputSchema,
|
|
113
|
+
measurementPortfolioSummaryQuerySchema,
|
|
114
|
+
measurementPropertyCompetitorsQuerySchema,
|
|
115
|
+
measurementPropertyQuestionsQuerySchema,
|
|
116
|
+
measurementQuerySetUpsertRequestSchema,
|
|
117
|
+
measurementQueryTemplateApplyRequestSchema,
|
|
118
|
+
measurementQueryTemplateUpsertRequestSchema,
|
|
119
|
+
measurementQuestionResultQuerySchema,
|
|
104
120
|
normalizeProjectAliases,
|
|
105
121
|
notificationEventSchema,
|
|
106
122
|
providerQuotaPolicySchema,
|
|
107
123
|
resolveProviderInput,
|
|
108
124
|
winnabilityClassSchema
|
|
109
|
-
} from "./chunk-
|
|
125
|
+
} from "./chunk-BVOU4UJM.js";
|
|
110
126
|
|
|
111
127
|
// src/cli.ts
|
|
112
128
|
import { pathToFileURL } from "url";
|
|
@@ -15714,8 +15730,10 @@ Usage: ${usage}`, {
|
|
|
15714
15730
|
];
|
|
15715
15731
|
|
|
15716
15732
|
// src/commands/measurement-plan.ts
|
|
15733
|
+
import crypto3 from "crypto";
|
|
15717
15734
|
import fs16 from "fs";
|
|
15718
15735
|
import { parse } from "yaml";
|
|
15736
|
+
import { z as z2 } from "zod";
|
|
15719
15737
|
function readPlan(source) {
|
|
15720
15738
|
const content = source === "-" ? fs16.readFileSync(0, "utf8") : fs16.readFileSync(source, "utf8");
|
|
15721
15739
|
const parsed = source.endsWith(".json") ? JSON.parse(content) : parse(content);
|
|
@@ -15726,6 +15744,171 @@ function readDiscoveryRule(source) {
|
|
|
15726
15744
|
const parsed = source.endsWith(".json") ? JSON.parse(content) : parse(content);
|
|
15727
15745
|
return measurementDiscoveryRuleSchema.parse(parsed);
|
|
15728
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
|
+
}
|
|
15729
15912
|
async function showMeasurementPlan(project, revision) {
|
|
15730
15913
|
const client = createApiClient();
|
|
15731
15914
|
console.log(JSON.stringify(revision === void 0 ? await client.getMeasurementPlan(project) : await client.getMeasurementPlanVersion(project, revision), null, 2));
|
|
@@ -15745,6 +15928,76 @@ async function publishMeasurementPlan(project, source) {
|
|
|
15745
15928
|
async function retireMeasurementPlanSegment(project, stableKey) {
|
|
15746
15929
|
console.log(JSON.stringify(await createApiClient().retireMeasurementPlanSegment(project, stableKey), null, 2));
|
|
15747
15930
|
}
|
|
15931
|
+
async function measurementAssignmentRequest(project, opts) {
|
|
15932
|
+
const client = createApiClient();
|
|
15933
|
+
const current = await client.getMeasurementPlanDraft(project);
|
|
15934
|
+
if (!current.draft || !current.etag) {
|
|
15935
|
+
throw new Error(`Project "${project}" has no Advanced Measurement draft. Start setup in the dashboard or create a draft first.`);
|
|
15936
|
+
}
|
|
15937
|
+
const targetKeys = opts.allProperties ? current.draft.authoring.targets.filter((target) => target.status === "included").map((target) => target.stableKey) : opts.targetKeys;
|
|
15938
|
+
return {
|
|
15939
|
+
client,
|
|
15940
|
+
request: {
|
|
15941
|
+
...targetKeys?.length ? { targetKeys } : {},
|
|
15942
|
+
...opts.groupKeys?.length ? { groupKeys: opts.groupKeys } : {},
|
|
15943
|
+
queryIds: opts.queryIds
|
|
15944
|
+
}
|
|
15945
|
+
};
|
|
15946
|
+
}
|
|
15947
|
+
async function previewMeasurementPlanAssignments(project, opts) {
|
|
15948
|
+
const { client, request } = await measurementAssignmentRequest(project, opts);
|
|
15949
|
+
console.log(JSON.stringify(await client.previewMeasurementDraftAssignments(project, request), null, 2));
|
|
15950
|
+
}
|
|
15951
|
+
async function applyMeasurementPlanAssignments(project, opts) {
|
|
15952
|
+
const { client, request } = await measurementAssignmentRequest(project, opts);
|
|
15953
|
+
const preview = await client.previewMeasurementDraftAssignments(project, request);
|
|
15954
|
+
const result = await client.applyMeasurementDraftAssignments(
|
|
15955
|
+
project,
|
|
15956
|
+
request,
|
|
15957
|
+
crypto3.randomUUID(),
|
|
15958
|
+
preview.draftEtag
|
|
15959
|
+
);
|
|
15960
|
+
console.log(JSON.stringify({ preview, result }, null, 2));
|
|
15961
|
+
}
|
|
15962
|
+
async function replaceMeasurementPlanAssignments(project, opts) {
|
|
15963
|
+
const { client, request } = await measurementAssignmentRequest(project, opts);
|
|
15964
|
+
const preview = await client.previewMeasurementDraftAssignments(project, request);
|
|
15965
|
+
const result = await client.replaceMeasurementDraftAssignments(
|
|
15966
|
+
project,
|
|
15967
|
+
request,
|
|
15968
|
+
crypto3.randomUUID(),
|
|
15969
|
+
preview.draftEtag
|
|
15970
|
+
);
|
|
15971
|
+
console.log(JSON.stringify({ preview, result }, null, 2));
|
|
15972
|
+
}
|
|
15973
|
+
function readGroupMembershipCsv(source) {
|
|
15974
|
+
return source === "-" ? fs16.readFileSync(0, "utf8") : fs16.readFileSync(source, "utf8");
|
|
15975
|
+
}
|
|
15976
|
+
async function previewMeasurementPlanGroups(project, source) {
|
|
15977
|
+
const preview = await createApiClient().previewMeasurementDraftGroupMembership(project, {
|
|
15978
|
+
csv: readGroupMembershipCsv(source)
|
|
15979
|
+
});
|
|
15980
|
+
console.log(JSON.stringify(preview, null, 2));
|
|
15981
|
+
}
|
|
15982
|
+
async function applyMeasurementPlanGroups(project, source, opts) {
|
|
15983
|
+
const client = createApiClient();
|
|
15984
|
+
const csv = readGroupMembershipCsv(source);
|
|
15985
|
+
const preview = await client.previewMeasurementDraftGroupMembership(project, { csv });
|
|
15986
|
+
if (preview.counts.needsAttention > 0 && !opts.acknowledgeSkipped) {
|
|
15987
|
+
throw new Error(
|
|
15988
|
+
`${preview.counts.needsAttention} CSV rows need attention. Correct them or add --acknowledge-skipped to apply only the selected matched rows.`
|
|
15989
|
+
);
|
|
15990
|
+
}
|
|
15991
|
+
const acceptedRows = opts.acceptAllMatched ? preview.rows.filter((row) => row.status === "matched").map((row) => row.dataRow) : opts.acceptedRows ?? [];
|
|
15992
|
+
if (acceptedRows.length === 0) throw new Error("No matched CSV rows were selected for apply.");
|
|
15993
|
+
const result = await client.applyMeasurementDraftGroupMembership(project, {
|
|
15994
|
+
csv,
|
|
15995
|
+
sourceChecksum: preview.sourceChecksum,
|
|
15996
|
+
previewChecksum: preview.previewChecksum,
|
|
15997
|
+
acceptedRows
|
|
15998
|
+
}, crypto3.randomUUID(), preview.draftEtag);
|
|
15999
|
+
console.log(JSON.stringify({ preview, result }, null, 2));
|
|
16000
|
+
}
|
|
15748
16001
|
async function discoverMeasurementTargets(project, sitemapUrl, ruleSource, maxUrls) {
|
|
15749
16002
|
const request = measurementDiscoveryRequestSchema.parse({
|
|
15750
16003
|
sitemapUrl,
|
|
@@ -15801,6 +16054,11 @@ function printMeasurementProperty(response) {
|
|
|
15801
16054
|
}
|
|
15802
16055
|
console.log(lines.join("\n"));
|
|
15803
16056
|
}
|
|
16057
|
+
function shapedPage(response) {
|
|
16058
|
+
if (response.answers !== void 0) return { shape: MeasurementEvidenceShapes.answers, ...response.answers };
|
|
16059
|
+
if (response.evidence !== void 0) return { shape: MeasurementEvidenceShapes.sources, ...response.evidence };
|
|
16060
|
+
throw systemError("The measurement property evidence response carried neither an evidence nor an answers page.");
|
|
16061
|
+
}
|
|
15804
16062
|
async function showMeasurementPropertyEvidence(project, opts) {
|
|
15805
16063
|
const response = await createApiClient().getMeasurementPropertyEvidence(project, {
|
|
15806
16064
|
targetKey: opts.targetKey,
|
|
@@ -15808,19 +16066,22 @@ async function showMeasurementPropertyEvidence(project, opts) {
|
|
|
15808
16066
|
...opts.provider === void 0 ? {} : { provider: opts.provider },
|
|
15809
16067
|
...opts.location === void 0 ? {} : { location: opts.location },
|
|
15810
16068
|
...opts.runId === void 0 ? {} : { runId: opts.runId },
|
|
16069
|
+
...opts.shape === void 0 ? {} : { shape: opts.shape },
|
|
15811
16070
|
...opts.cursor === void 0 ? {} : { cursor: opts.cursor },
|
|
15812
16071
|
...opts.limit === void 0 ? {} : { limit: opts.limit }
|
|
15813
16072
|
});
|
|
15814
16073
|
if (opts.format === "jsonl") {
|
|
16074
|
+
const page = shapedPage(response);
|
|
15815
16075
|
emitJsonl([{
|
|
15816
16076
|
kind: "measurement-property-evidence-header",
|
|
16077
|
+
shape: page.shape,
|
|
15817
16078
|
property: response.property,
|
|
15818
16079
|
queryClass: response.queryClass,
|
|
15819
16080
|
measurement: response.measurement,
|
|
15820
|
-
totalEstimate:
|
|
15821
|
-
nextCursor:
|
|
16081
|
+
totalEstimate: page.totalEstimate ?? null,
|
|
16082
|
+
nextCursor: page.nextCursor ?? null
|
|
15822
16083
|
}]);
|
|
15823
|
-
emitJsonl(
|
|
16084
|
+
emitJsonl(page.items);
|
|
15824
16085
|
return;
|
|
15825
16086
|
}
|
|
15826
16087
|
if (opts.format === "json") {
|
|
@@ -15829,6 +16090,10 @@ async function showMeasurementPropertyEvidence(project, opts) {
|
|
|
15829
16090
|
}
|
|
15830
16091
|
printMeasurementPropertyEvidence(response);
|
|
15831
16092
|
}
|
|
16093
|
+
function signalText(signal) {
|
|
16094
|
+
if (signal === null) return "not measured";
|
|
16095
|
+
return signal ? "yes" : "no";
|
|
16096
|
+
}
|
|
15832
16097
|
function printMeasurementPropertyEvidence(response) {
|
|
15833
16098
|
const lines = [];
|
|
15834
16099
|
lines.push(`${response.property.label} \u2014 ${response.queryClass} questions`);
|
|
@@ -15837,18 +16102,28 @@ function printMeasurementPropertyEvidence(response) {
|
|
|
15837
16102
|
console.log(lines.join("\n"));
|
|
15838
16103
|
return;
|
|
15839
16104
|
}
|
|
15840
|
-
const page = response
|
|
16105
|
+
const page = shapedPage(response);
|
|
16106
|
+
const answerShape = page.shape === MeasurementEvidenceShapes.answers;
|
|
15841
16107
|
lines.push(`Measurement: ${response.measurement.state}${response.measurement.displayedRunId ? ` \xB7 run ${response.measurement.displayedRunId}` : ""}`);
|
|
15842
16108
|
if (page.items.length === 0) {
|
|
15843
|
-
lines.push("No source evidence matched this Property in the displayed run.");
|
|
16109
|
+
lines.push(answerShape ? "No answers matched this Property in the displayed run." : "No source evidence matched this Property in the displayed run.");
|
|
15844
16110
|
console.log(lines.join("\n"));
|
|
15845
16111
|
return;
|
|
15846
16112
|
}
|
|
15847
|
-
lines.push(`${page.items.length} of ${page.totalEstimate ?? page.items.length} evidence rows`);
|
|
16113
|
+
lines.push(`${page.items.length} of ${page.totalEstimate ?? page.items.length} ${answerShape ? "answers" : "evidence rows"}`);
|
|
15848
16114
|
lines.push("");
|
|
15849
|
-
|
|
15850
|
-
|
|
15851
|
-
|
|
16115
|
+
if (page.shape === MeasurementEvidenceShapes.answers) {
|
|
16116
|
+
lines.push(`${"Engine".padEnd(12)}${"Question".padEnd(40)}${"Mentioned".padEnd(15)}${"Cited".padEnd(8)}Sources`);
|
|
16117
|
+
for (const item of page.items) {
|
|
16118
|
+
lines.push(
|
|
16119
|
+
`${item.provider.padEnd(12)}${item.queryText.slice(0, 39).padEnd(40)}${signalText(item.mentioned).padEnd(15)}${signalText(item.cited).padEnd(8)}${item.sources.length}`
|
|
16120
|
+
);
|
|
16121
|
+
}
|
|
16122
|
+
} else {
|
|
16123
|
+
lines.push(`${"Match".padEnd(14)}${"Engine".padEnd(12)}${"Question".padEnd(40)}URL`);
|
|
16124
|
+
for (const item of page.items) {
|
|
16125
|
+
lines.push(`${item.classification.padEnd(14)}${item.provider.padEnd(12)}${item.queryText.slice(0, 39).padEnd(40)}${item.sourceUrl}`);
|
|
16126
|
+
}
|
|
15852
16127
|
}
|
|
15853
16128
|
if (page.nextCursor) lines.push(`
|
|
15854
16129
|
More rows: --cursor ${page.nextCursor}`);
|
|
@@ -15857,6 +16132,7 @@ More rows: --cursor ${page.nextCursor}`);
|
|
|
15857
16132
|
|
|
15858
16133
|
// src/cli-commands/measurement-plan.ts
|
|
15859
16134
|
var QUERY_CLASSES = ["all", "branded", "non-brand"];
|
|
16135
|
+
var EVIDENCE_SHAPES = ["sources", "answers"];
|
|
15860
16136
|
function queryClassOption(input) {
|
|
15861
16137
|
const value = getString(input.values, "query-class");
|
|
15862
16138
|
if (value === void 0) return void 0;
|
|
@@ -15864,6 +16140,13 @@ function queryClassOption(input) {
|
|
|
15864
16140
|
if (!match) throw usageError(`--query-class must be one of ${QUERY_CLASSES.join(", ")}`);
|
|
15865
16141
|
return match;
|
|
15866
16142
|
}
|
|
16143
|
+
function shapeOption(input) {
|
|
16144
|
+
const value = getString(input.values, "shape");
|
|
16145
|
+
if (value === void 0) return void 0;
|
|
16146
|
+
const match = EVIDENCE_SHAPES.find((candidate) => candidate === value);
|
|
16147
|
+
if (!match) throw usageError(`--shape must be one of ${EVIDENCE_SHAPES.join(", ")}`);
|
|
16148
|
+
return match;
|
|
16149
|
+
}
|
|
15867
16150
|
function propertyScope(input, command, usage) {
|
|
15868
16151
|
return {
|
|
15869
16152
|
targetKey: requireStringOption(input, "target-key", { command, usage, message: "--target-key is required" }),
|
|
@@ -15881,6 +16164,36 @@ var PROPERTY_SCOPE_OPTIONS = {
|
|
|
15881
16164
|
location: stringOption(),
|
|
15882
16165
|
"run-id": stringOption()
|
|
15883
16166
|
};
|
|
16167
|
+
var ASSIGNMENT_AUDIENCE_OPTIONS = {
|
|
16168
|
+
group: multiStringOption(),
|
|
16169
|
+
"target-key": multiStringOption(),
|
|
16170
|
+
"all-properties": { type: "boolean" },
|
|
16171
|
+
"query-id": multiStringOption()
|
|
16172
|
+
};
|
|
16173
|
+
function assignmentAudience(input, command, usage) {
|
|
16174
|
+
const project = requireProject(input, command, usage);
|
|
16175
|
+
const groupKeys = getStringArray(input.values, "group")?.map((value) => value.trim()).filter(Boolean);
|
|
16176
|
+
const targetKeys = getStringArray(input.values, "target-key")?.map((value) => value.trim()).filter(Boolean);
|
|
16177
|
+
const queryIds = getStringArray(input.values, "query-id")?.map((value) => value.trim()).filter(Boolean) ?? [];
|
|
16178
|
+
const allProperties = getBoolean(input.values, "all-properties");
|
|
16179
|
+
if (queryIds.length === 0) throw usageError(`Error: at least one --query-id is required
|
|
16180
|
+
Usage: ${usage}`);
|
|
16181
|
+
if (allProperties && ((groupKeys?.length ?? 0) > 0 || (targetKeys?.length ?? 0) > 0)) {
|
|
16182
|
+
throw usageError(`Error: --all-properties cannot be combined with --group or --target-key
|
|
16183
|
+
Usage: ${usage}`);
|
|
16184
|
+
}
|
|
16185
|
+
if (!allProperties && (groupKeys?.length ?? 0) === 0 && (targetKeys?.length ?? 0) === 0) {
|
|
16186
|
+
throw usageError(`Error: select at least one --group, --target-key, or --all-properties
|
|
16187
|
+
Usage: ${usage}`);
|
|
16188
|
+
}
|
|
16189
|
+
return { project, options: { groupKeys, targetKeys, queryIds, allProperties } };
|
|
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
|
+
}
|
|
15884
16197
|
var MEASUREMENT_PLAN_CLI_COMMANDS = [
|
|
15885
16198
|
{ path: ["measurement-plan", "show"], usage: "canonry measurement-plan show <project> [--revision N] [--format json]", options: { revision: stringOption() }, run: async (input) => {
|
|
15886
16199
|
const value = getString(input.values, "revision");
|
|
@@ -15901,6 +16214,95 @@ var MEASUREMENT_PLAN_CLI_COMMANDS = [
|
|
|
15901
16214
|
if (!stableKey) throw usageError("stable segment key is required");
|
|
15902
16215
|
return retireMeasurementPlanSegment(project, stableKey);
|
|
15903
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
|
+
},
|
|
16227
|
+
{
|
|
16228
|
+
path: ["measurement-plan", "assignments", "preview"],
|
|
16229
|
+
usage: "canonry measurement-plan assignments preview <project> [--group KEY ...] [--target-key KEY ... | --all-properties] --query-id ID [--query-id ID ...] [--format json]",
|
|
16230
|
+
options: ASSIGNMENT_AUDIENCE_OPTIONS,
|
|
16231
|
+
run: (input) => {
|
|
16232
|
+
const usage = "canonry measurement-plan assignments preview <project> [--group KEY ...] [--target-key KEY ... | --all-properties] --query-id ID [--query-id ID ...]";
|
|
16233
|
+
const { project, options } = assignmentAudience(input, "measurement-plan.assignments.preview", usage);
|
|
16234
|
+
return previewMeasurementPlanAssignments(project, options);
|
|
16235
|
+
}
|
|
16236
|
+
},
|
|
16237
|
+
{
|
|
16238
|
+
path: ["measurement-plan", "assignments", "apply"],
|
|
16239
|
+
usage: "canonry measurement-plan assignments apply <project> [--group KEY ...] [--target-key KEY ... | --all-properties] --query-id ID [--query-id ID ...] [--format json]",
|
|
16240
|
+
options: ASSIGNMENT_AUDIENCE_OPTIONS,
|
|
16241
|
+
run: (input) => {
|
|
16242
|
+
const usage = "canonry measurement-plan assignments apply <project> [--group KEY ...] [--target-key KEY ... | --all-properties] --query-id ID [--query-id ID ...]";
|
|
16243
|
+
const { project, options } = assignmentAudience(input, "measurement-plan.assignments.apply", usage);
|
|
16244
|
+
return applyMeasurementPlanAssignments(project, options);
|
|
16245
|
+
}
|
|
16246
|
+
},
|
|
16247
|
+
{
|
|
16248
|
+
path: ["measurement-plan", "assignments", "replace"],
|
|
16249
|
+
usage: "canonry measurement-plan assignments replace <project> [--group KEY ...] [--target-key KEY ... | --all-properties] --query-id ID [--query-id ID ...] --confirm [--format json]",
|
|
16250
|
+
options: { ...ASSIGNMENT_AUDIENCE_OPTIONS, confirm: { type: "boolean" } },
|
|
16251
|
+
run: (input) => {
|
|
16252
|
+
const usage = "canonry measurement-plan assignments replace <project> [--group KEY ...] [--target-key KEY ... | --all-properties] --query-id ID [--query-id ID ...] --confirm";
|
|
16253
|
+
if (!getBoolean(input.values, "confirm")) throw usageError(`Error: --confirm is required
|
|
16254
|
+
Usage: ${usage}`);
|
|
16255
|
+
const { project, options } = assignmentAudience(input, "measurement-plan.assignments.replace", usage);
|
|
16256
|
+
return replaceMeasurementPlanAssignments(project, options);
|
|
16257
|
+
}
|
|
16258
|
+
},
|
|
16259
|
+
{
|
|
16260
|
+
path: ["measurement-plan", "groups", "preview"],
|
|
16261
|
+
usage: "canonry measurement-plan groups preview <project> <csv|-> [--format json]",
|
|
16262
|
+
run: (input) => {
|
|
16263
|
+
const usage = "canonry measurement-plan groups preview <project> <csv|->";
|
|
16264
|
+
const project = requireProject(input, "measurement-plan.groups.preview", usage);
|
|
16265
|
+
const source = input.positionals[1];
|
|
16266
|
+
if (!source) throw usageError(`Error: CSV file path or - is required
|
|
16267
|
+
Usage: ${usage}`);
|
|
16268
|
+
return previewMeasurementPlanGroups(project, source);
|
|
16269
|
+
}
|
|
16270
|
+
},
|
|
16271
|
+
{
|
|
16272
|
+
path: ["measurement-plan", "groups", "apply"],
|
|
16273
|
+
usage: "canonry measurement-plan groups apply <project> <csv|-> --confirm [--accept-row N ... | --accept-all-matched] [--acknowledge-skipped] [--format json]",
|
|
16274
|
+
options: {
|
|
16275
|
+
confirm: { type: "boolean" },
|
|
16276
|
+
"accept-row": multiStringOption(),
|
|
16277
|
+
"accept-all-matched": { type: "boolean" },
|
|
16278
|
+
"acknowledge-skipped": { type: "boolean" }
|
|
16279
|
+
},
|
|
16280
|
+
run: (input) => {
|
|
16281
|
+
const usage = "canonry measurement-plan groups apply <project> <csv|-> --confirm [--accept-row N ... | --accept-all-matched] [--acknowledge-skipped]";
|
|
16282
|
+
const project = requireProject(input, "measurement-plan.groups.apply", usage);
|
|
16283
|
+
const source = input.positionals[1];
|
|
16284
|
+
if (!source) throw usageError(`Error: CSV file path or - is required
|
|
16285
|
+
Usage: ${usage}`);
|
|
16286
|
+
if (!getBoolean(input.values, "confirm")) throw usageError(`Error: --confirm is required
|
|
16287
|
+
Usage: ${usage}`);
|
|
16288
|
+
const acceptAllMatched = getBoolean(input.values, "accept-all-matched");
|
|
16289
|
+
const rowValues = getStringArray(input.values, "accept-row") ?? [];
|
|
16290
|
+
if (acceptAllMatched === rowValues.length > 0) {
|
|
16291
|
+
throw usageError(`Error: choose exactly one of --accept-row or --accept-all-matched
|
|
16292
|
+
Usage: ${usage}`);
|
|
16293
|
+
}
|
|
16294
|
+
const acceptedRows = rowValues.map((value) => Number(value));
|
|
16295
|
+
if (acceptedRows.some((row) => !Number.isSafeInteger(row) || row < 1)) {
|
|
16296
|
+
throw usageError(`Error: --accept-row must be a positive integer
|
|
16297
|
+
Usage: ${usage}`);
|
|
16298
|
+
}
|
|
16299
|
+
return applyMeasurementPlanGroups(project, source, {
|
|
16300
|
+
acceptedRows,
|
|
16301
|
+
acceptAllMatched,
|
|
16302
|
+
acknowledgeSkipped: getBoolean(input.values, "acknowledge-skipped")
|
|
16303
|
+
});
|
|
16304
|
+
}
|
|
16305
|
+
},
|
|
15904
16306
|
{
|
|
15905
16307
|
path: ["measurement-plan", "discover"],
|
|
15906
16308
|
usage: "canonry measurement-plan discover <project> --sitemap-url <url> --rule <yaml|json|-> [--max-urls N] [--format json]",
|
|
@@ -15952,8 +16354,8 @@ var MEASUREMENT_PLAN_CLI_COMMANDS = [
|
|
|
15952
16354
|
},
|
|
15953
16355
|
{
|
|
15954
16356
|
path: ["measurement-plan", "property-evidence"],
|
|
15955
|
-
usage: "canonry measurement-plan property-evidence <project> --target-key <key> [--query-class all|branded|non-brand] [--provider <p>] [--location <l>] [--run-id <id>] [--cursor <c>] [--limit N] [--format json|jsonl]",
|
|
15956
|
-
options: { ...PROPERTY_SCOPE_OPTIONS, cursor: stringOption(), limit: stringOption() },
|
|
16357
|
+
usage: "canonry measurement-plan property-evidence <project> --target-key <key> [--query-class all|branded|non-brand] [--provider <p>] [--location <l>] [--run-id <id>] [--shape sources|answers] [--cursor <c>] [--limit N] [--format json|jsonl]",
|
|
16358
|
+
options: { ...PROPERTY_SCOPE_OPTIONS, shape: stringOption(), cursor: stringOption(), limit: stringOption() },
|
|
15957
16359
|
run: (input) => {
|
|
15958
16360
|
const usage = "canonry measurement-plan property-evidence <project> --target-key <key>";
|
|
15959
16361
|
const project = requireProject(input, "measurement-plan.property-evidence", usage);
|
|
@@ -15962,8 +16364,10 @@ var MEASUREMENT_PLAN_CLI_COMMANDS = [
|
|
|
15962
16364
|
if (limit !== void 0 && (!Number.isInteger(limit) || limit < 1 || limit > 100)) {
|
|
15963
16365
|
throw usageError("--limit must be an integer from 1 to 100");
|
|
15964
16366
|
}
|
|
16367
|
+
const shape = shapeOption(input);
|
|
15965
16368
|
return showMeasurementPropertyEvidence(project, {
|
|
15966
16369
|
...propertyScope(input, "measurement-plan.property-evidence", usage),
|
|
16370
|
+
...shape === void 0 ? {} : { shape },
|
|
15967
16371
|
cursor: getString(input.values, "cursor"),
|
|
15968
16372
|
...limit === void 0 ? {} : { limit }
|
|
15969
16373
|
});
|
package/dist/index.js
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import {
|
|
2
2
|
createServer
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-GNKVF6TZ.js";
|
|
4
4
|
import {
|
|
5
5
|
loadConfig
|
|
6
|
-
} from "./chunk-
|
|
7
|
-
import "./chunk-
|
|
8
|
-
import "./chunk-
|
|
6
|
+
} from "./chunk-2NTWZHNF.js";
|
|
7
|
+
import "./chunk-ZRUNFIGA.js";
|
|
8
|
+
import "./chunk-BVOU4UJM.js";
|
|
9
9
|
export {
|
|
10
10
|
createServer,
|
|
11
11
|
loadConfig
|
package/dist/mcp.js
CHANGED
|
@@ -3,10 +3,10 @@ import {
|
|
|
3
3
|
PACKAGE_VERSION,
|
|
4
4
|
canonryMcpTools,
|
|
5
5
|
createApiClient
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-2NTWZHNF.js";
|
|
7
7
|
import {
|
|
8
8
|
isReadOnlyKey
|
|
9
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-BVOU4UJM.js";
|
|
10
10
|
|
|
11
11
|
// src/mcp/cli.ts
|
|
12
12
|
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
@@ -110,9 +110,9 @@ var CANONRY_MCP_TOOLKIT_NAMES = ["monitoring", "setup", "gsc", "ga", "gbp", "ads
|
|
|
110
110
|
var CANONRY_MCP_TOOLKITS = [
|
|
111
111
|
{
|
|
112
112
|
name: "monitoring",
|
|
113
|
-
title: "
|
|
114
|
-
description: "Inspect
|
|
115
|
-
whenToLoad: "Load when
|
|
113
|
+
title: "Measurement, runs, insights, health",
|
|
114
|
+
description: "Inspect portfolio and Property measurement, question results, run history, intelligence insights, and health timelines.",
|
|
115
|
+
whenToLoad: "Load when finding weak Properties, reviewing answers and competitors, checking data quality, comparing runs, or investigating regressions."
|
|
116
116
|
},
|
|
117
117
|
{
|
|
118
118
|
name: "setup",
|