@canonry/canonry 4.145.0 → 4.147.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/assets/assets/{AuditHistoryPanel-CV9g5mLR.js → AuditHistoryPanel-DiQ0Ynw5.js} +1 -1
- package/assets/assets/{BacklinksPage-RTcYKA5I.js → BacklinksPage-DLUQuPE_.js} +1 -1
- package/assets/assets/{ChartPrimitives-BMR0Dqnf.js → ChartPrimitives-BoEy1qo7.js} +1 -1
- package/assets/assets/{HistoryPage-DAN9QO6x.js → HistoryPage-mYR2vk8n.js} +1 -1
- package/assets/assets/MeasurementPropertyPage-BocyGHJN.js +1 -0
- package/assets/assets/ProjectPage-Q5wQ7nSW.js +12 -0
- package/assets/assets/{RunRow-WDCIS9MJ.js → RunRow-Ct-A6H9e.js} +1 -1
- package/assets/assets/{RunsPage-D3Zxd6oc.js → RunsPage-CsDtq0Qw.js} +1 -1
- package/assets/assets/{SettingsPage-DcCFVeA7.js → SettingsPage-BXwFGc1P.js} +1 -1
- package/assets/assets/{TrafficPage-D0tPBu5O.js → TrafficPage-B2omyoI8.js} +1 -1
- package/assets/assets/{TrafficSourceDetailPage-CtyEE9eJ.js → TrafficSourceDetailPage-CoEqc6OJ.js} +1 -1
- package/assets/assets/{arrow-left-hBxXIGS1.js → arrow-left-Dh0vsQxe.js} +1 -1
- package/assets/assets/{extract-error-message-DRu89RHb.js → extract-error-message-DvWJ0xRn.js} +1 -1
- package/assets/assets/index-CXe6S1ey.css +1 -0
- package/assets/assets/index-FE8JPHmT.js +213 -0
- package/assets/assets/{trash-2-DP0ukgbl.js → trash-2-D1_8ZseY.js} +1 -1
- package/assets/assets/v2-overview-adapter-owDeFdUc.js +1 -0
- package/assets/assets/{vendor-markdown-6dwjPOKK.js → vendor-markdown-CpDJch4G.js} +1 -1
- package/assets/assets/{vendor-radix-CQ77EO2y.js → vendor-radix-DnzzbllM.js} +1 -1
- package/assets/assets/{vendor-recharts-DSxTZhaH.js → vendor-recharts-33ACLxsD.js} +1 -1
- package/assets/assets/vendor-tanstack-BjS7iY3g.js +1 -0
- package/assets/index.html +6 -6
- package/dist/{chunk-MBLATP5L.js → chunk-4BL24FQA.js} +485 -8
- package/dist/{chunk-EFBTZ6ZT.js → chunk-BVOU4UJM.js} +3753 -3018
- package/dist/{chunk-GTBCGJNT.js → chunk-DRDNHYIF.js} +4397 -1501
- package/dist/{chunk-XNAJXSZ2.js → chunk-ZDYS24LW.js} +4 -4
- package/dist/cli.js +364 -4
- package/dist/index.js +4 -4
- package/dist/{intelligence-service-DVMEVHAG.js → intelligence-service-7CGZ537D.js} +2 -2
- package/dist/mcp.js +5 -5
- package/package.json +11 -10
- package/assets/assets/ProjectPage-aFV2nddp.js +0 -9
- package/assets/assets/index-ANFzZ3nU.css +0 -1
- package/assets/assets/index-DSOfEiTH.js +0 -213
- package/assets/assets/vendor-tanstack-Be8JdV5M.js +0 -1
|
@@ -10,7 +10,7 @@ import {
|
|
|
10
10
|
loadConfig,
|
|
11
11
|
loadConfigRaw,
|
|
12
12
|
saveConfigPatch
|
|
13
|
-
} from "./chunk-
|
|
13
|
+
} from "./chunk-4BL24FQA.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-
|
|
129
|
+
} from "./chunk-DRDNHYIF.js";
|
|
130
130
|
import {
|
|
131
131
|
AGENT_MEMORY_VALUE_MAX_BYTES,
|
|
132
132
|
AGENT_PROVIDER_IDS,
|
|
@@ -217,7 +217,7 @@ import {
|
|
|
217
217
|
validationError,
|
|
218
218
|
winnabilityClassLabel,
|
|
219
219
|
withRetry
|
|
220
|
-
} from "./chunk-
|
|
220
|
+
} from "./chunk-BVOU4UJM.js";
|
|
221
221
|
|
|
222
222
|
// src/telemetry.ts
|
|
223
223
|
import crypto from "crypto";
|
|
@@ -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-
|
|
7423
|
+
const { IntelligenceService: IntelligenceService2 } = await import("./intelligence-service-7CGZ537D.js");
|
|
7424
7424
|
const config = loadConfig();
|
|
7425
7425
|
const db = createClient(config.database);
|
|
7426
7426
|
migrate(db);
|
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-ZDYS24LW.js";
|
|
34
34
|
import {
|
|
35
35
|
CliError,
|
|
36
36
|
EXIT_SYSTEM_ERROR,
|
|
@@ -46,8 +46,9 @@ import {
|
|
|
46
46
|
printCliError,
|
|
47
47
|
saveConfig,
|
|
48
48
|
saveConfigPatch,
|
|
49
|
+
systemError,
|
|
49
50
|
usageError
|
|
50
|
-
} from "./chunk-
|
|
51
|
+
} from "./chunk-4BL24FQA.js";
|
|
51
52
|
import {
|
|
52
53
|
apiKeys,
|
|
53
54
|
createClient,
|
|
@@ -55,7 +56,7 @@ import {
|
|
|
55
56
|
projects,
|
|
56
57
|
queries,
|
|
57
58
|
renderReportHtml
|
|
58
|
-
} from "./chunk-
|
|
59
|
+
} from "./chunk-DRDNHYIF.js";
|
|
59
60
|
import {
|
|
60
61
|
AdsDeliverySnapshotStatuses,
|
|
61
62
|
AdsHistoricalCampaignRollupStatuses,
|
|
@@ -68,6 +69,7 @@ import {
|
|
|
68
69
|
CheckScopes,
|
|
69
70
|
CheckStatuses,
|
|
70
71
|
CitationStates,
|
|
72
|
+
MeasurementEvidenceShapes,
|
|
71
73
|
READ_ONLY_SCOPE,
|
|
72
74
|
REPORT_PERIOD_OPTIONS,
|
|
73
75
|
ResearchRunStatuses,
|
|
@@ -106,7 +108,7 @@ import {
|
|
|
106
108
|
providerQuotaPolicySchema,
|
|
107
109
|
resolveProviderInput,
|
|
108
110
|
winnabilityClassSchema
|
|
109
|
-
} from "./chunk-
|
|
111
|
+
} from "./chunk-BVOU4UJM.js";
|
|
110
112
|
|
|
111
113
|
// src/cli.ts
|
|
112
114
|
import { pathToFileURL } from "url";
|
|
@@ -15714,6 +15716,7 @@ Usage: ${usage}`, {
|
|
|
15714
15716
|
];
|
|
15715
15717
|
|
|
15716
15718
|
// src/commands/measurement-plan.ts
|
|
15719
|
+
import crypto3 from "crypto";
|
|
15717
15720
|
import fs16 from "fs";
|
|
15718
15721
|
import { parse } from "yaml";
|
|
15719
15722
|
function readPlan(source) {
|
|
@@ -15745,6 +15748,76 @@ async function publishMeasurementPlan(project, source) {
|
|
|
15745
15748
|
async function retireMeasurementPlanSegment(project, stableKey) {
|
|
15746
15749
|
console.log(JSON.stringify(await createApiClient().retireMeasurementPlanSegment(project, stableKey), null, 2));
|
|
15747
15750
|
}
|
|
15751
|
+
async function measurementAssignmentRequest(project, opts) {
|
|
15752
|
+
const client = createApiClient();
|
|
15753
|
+
const current = await client.getMeasurementPlanDraft(project);
|
|
15754
|
+
if (!current.draft || !current.etag) {
|
|
15755
|
+
throw new Error(`Project "${project}" has no Advanced Measurement draft. Start setup in the dashboard or create a draft first.`);
|
|
15756
|
+
}
|
|
15757
|
+
const targetKeys = opts.allProperties ? current.draft.authoring.targets.filter((target) => target.status === "included").map((target) => target.stableKey) : opts.targetKeys;
|
|
15758
|
+
return {
|
|
15759
|
+
client,
|
|
15760
|
+
request: {
|
|
15761
|
+
...targetKeys?.length ? { targetKeys } : {},
|
|
15762
|
+
...opts.groupKeys?.length ? { groupKeys: opts.groupKeys } : {},
|
|
15763
|
+
queryIds: opts.queryIds
|
|
15764
|
+
}
|
|
15765
|
+
};
|
|
15766
|
+
}
|
|
15767
|
+
async function previewMeasurementPlanAssignments(project, opts) {
|
|
15768
|
+
const { client, request } = await measurementAssignmentRequest(project, opts);
|
|
15769
|
+
console.log(JSON.stringify(await client.previewMeasurementDraftAssignments(project, request), null, 2));
|
|
15770
|
+
}
|
|
15771
|
+
async function applyMeasurementPlanAssignments(project, opts) {
|
|
15772
|
+
const { client, request } = await measurementAssignmentRequest(project, opts);
|
|
15773
|
+
const preview = await client.previewMeasurementDraftAssignments(project, request);
|
|
15774
|
+
const result = await client.applyMeasurementDraftAssignments(
|
|
15775
|
+
project,
|
|
15776
|
+
request,
|
|
15777
|
+
crypto3.randomUUID(),
|
|
15778
|
+
preview.draftEtag
|
|
15779
|
+
);
|
|
15780
|
+
console.log(JSON.stringify({ preview, result }, null, 2));
|
|
15781
|
+
}
|
|
15782
|
+
async function replaceMeasurementPlanAssignments(project, opts) {
|
|
15783
|
+
const { client, request } = await measurementAssignmentRequest(project, opts);
|
|
15784
|
+
const preview = await client.previewMeasurementDraftAssignments(project, request);
|
|
15785
|
+
const result = await client.replaceMeasurementDraftAssignments(
|
|
15786
|
+
project,
|
|
15787
|
+
request,
|
|
15788
|
+
crypto3.randomUUID(),
|
|
15789
|
+
preview.draftEtag
|
|
15790
|
+
);
|
|
15791
|
+
console.log(JSON.stringify({ preview, result }, null, 2));
|
|
15792
|
+
}
|
|
15793
|
+
function readGroupMembershipCsv(source) {
|
|
15794
|
+
return source === "-" ? fs16.readFileSync(0, "utf8") : fs16.readFileSync(source, "utf8");
|
|
15795
|
+
}
|
|
15796
|
+
async function previewMeasurementPlanGroups(project, source) {
|
|
15797
|
+
const preview = await createApiClient().previewMeasurementDraftGroupMembership(project, {
|
|
15798
|
+
csv: readGroupMembershipCsv(source)
|
|
15799
|
+
});
|
|
15800
|
+
console.log(JSON.stringify(preview, null, 2));
|
|
15801
|
+
}
|
|
15802
|
+
async function applyMeasurementPlanGroups(project, source, opts) {
|
|
15803
|
+
const client = createApiClient();
|
|
15804
|
+
const csv = readGroupMembershipCsv(source);
|
|
15805
|
+
const preview = await client.previewMeasurementDraftGroupMembership(project, { csv });
|
|
15806
|
+
if (preview.counts.needsAttention > 0 && !opts.acknowledgeSkipped) {
|
|
15807
|
+
throw new Error(
|
|
15808
|
+
`${preview.counts.needsAttention} CSV rows need attention. Correct them or add --acknowledge-skipped to apply only the selected matched rows.`
|
|
15809
|
+
);
|
|
15810
|
+
}
|
|
15811
|
+
const acceptedRows = opts.acceptAllMatched ? preview.rows.filter((row) => row.status === "matched").map((row) => row.dataRow) : opts.acceptedRows ?? [];
|
|
15812
|
+
if (acceptedRows.length === 0) throw new Error("No matched CSV rows were selected for apply.");
|
|
15813
|
+
const result = await client.applyMeasurementDraftGroupMembership(project, {
|
|
15814
|
+
csv,
|
|
15815
|
+
sourceChecksum: preview.sourceChecksum,
|
|
15816
|
+
previewChecksum: preview.previewChecksum,
|
|
15817
|
+
acceptedRows
|
|
15818
|
+
}, crypto3.randomUUID(), preview.draftEtag);
|
|
15819
|
+
console.log(JSON.stringify({ preview, result }, null, 2));
|
|
15820
|
+
}
|
|
15748
15821
|
async function discoverMeasurementTargets(project, sitemapUrl, ruleSource, maxUrls) {
|
|
15749
15822
|
const request = measurementDiscoveryRequestSchema.parse({
|
|
15750
15823
|
sitemapUrl,
|
|
@@ -15756,8 +15829,185 @@ async function discoverMeasurementTargets(project, sitemapUrl, ruleSource, maxUr
|
|
|
15756
15829
|
async function showMeasurementReport(project, revision) {
|
|
15757
15830
|
console.log(JSON.stringify(await createApiClient().getMeasurementReport(project, revision), null, 2));
|
|
15758
15831
|
}
|
|
15832
|
+
var METRIC_REASONS = {
|
|
15833
|
+
plan_v1: "not measured (setup update required)",
|
|
15834
|
+
no_completed_run: "not measured (no completed run)",
|
|
15835
|
+
no_population: "not measured (no questions of this type)",
|
|
15836
|
+
evidence_incomplete: "not measured (evidence incomplete)",
|
|
15837
|
+
not_applicable: "not measured (not applicable)"
|
|
15838
|
+
};
|
|
15839
|
+
function metricText(metric) {
|
|
15840
|
+
if (metric.state === "unavailable") return METRIC_REASONS[metric.reason] ?? `not measured (${metric.reason})`;
|
|
15841
|
+
const percent = `${Math.round(metric.value * 100)}%`;
|
|
15842
|
+
return metric.numerator === void 0 || metric.denominator === void 0 ? percent : `${metric.numerator} of ${metric.denominator} (${percent})`;
|
|
15843
|
+
}
|
|
15844
|
+
async function showMeasurementProperty(project, opts) {
|
|
15845
|
+
const response = await createApiClient().getMeasurementOverview(project, {
|
|
15846
|
+
scope: "property",
|
|
15847
|
+
targetKey: opts.targetKey,
|
|
15848
|
+
...opts.queryClass === void 0 ? {} : { queryClass: opts.queryClass },
|
|
15849
|
+
...opts.provider === void 0 ? {} : { provider: opts.provider },
|
|
15850
|
+
...opts.location === void 0 ? {} : { location: opts.location },
|
|
15851
|
+
...opts.runId === void 0 ? {} : { runId: opts.runId }
|
|
15852
|
+
});
|
|
15853
|
+
if (isMachineFormat(opts.format)) {
|
|
15854
|
+
console.log(JSON.stringify(response, null, 2));
|
|
15855
|
+
return;
|
|
15856
|
+
}
|
|
15857
|
+
printMeasurementProperty(response);
|
|
15858
|
+
}
|
|
15859
|
+
function printMeasurementProperty(response) {
|
|
15860
|
+
const row = response.properties.items.at(0);
|
|
15861
|
+
const lines = [];
|
|
15862
|
+
lines.push(`${response.scope.label} \u2014 ${response.queryClass} questions`);
|
|
15863
|
+
lines.push(`Measurement: ${response.measurement.state}${response.measurement.displayedRunId ? ` \xB7 run ${response.measurement.displayedRunId}` : ""}`);
|
|
15864
|
+
lines.push("");
|
|
15865
|
+
lines.push(`Mentioned ${metricText(row ? row.mentionCoverage : response.metrics.mentionCoverage)}`);
|
|
15866
|
+
lines.push(`Cited ${metricText(row ? row.citationCoverage : response.metrics.citationCoverage)}`);
|
|
15867
|
+
if (row && row.flags > 0) lines.push(`Flagged ${row.flags} ${row.flags === 1 ? "result needs" : "results need"} review`);
|
|
15868
|
+
if (row && row.providers.length > 0) {
|
|
15869
|
+
lines.push("");
|
|
15870
|
+
lines.push(`${"Engine".padEnd(14)}${"Mentioned".padEnd(34)}Cited`);
|
|
15871
|
+
for (const provider of row.providers) {
|
|
15872
|
+
lines.push(`${provider.provider.padEnd(14)}${metricText(provider.mentionCoverage).padEnd(34)}${metricText(provider.citationCoverage)}`);
|
|
15873
|
+
}
|
|
15874
|
+
}
|
|
15875
|
+
console.log(lines.join("\n"));
|
|
15876
|
+
}
|
|
15877
|
+
function shapedPage(response) {
|
|
15878
|
+
if (response.answers !== void 0) return { shape: MeasurementEvidenceShapes.answers, ...response.answers };
|
|
15879
|
+
if (response.evidence !== void 0) return { shape: MeasurementEvidenceShapes.sources, ...response.evidence };
|
|
15880
|
+
throw systemError("The measurement property evidence response carried neither an evidence nor an answers page.");
|
|
15881
|
+
}
|
|
15882
|
+
async function showMeasurementPropertyEvidence(project, opts) {
|
|
15883
|
+
const response = await createApiClient().getMeasurementPropertyEvidence(project, {
|
|
15884
|
+
targetKey: opts.targetKey,
|
|
15885
|
+
...opts.queryClass === void 0 ? {} : { queryClass: opts.queryClass },
|
|
15886
|
+
...opts.provider === void 0 ? {} : { provider: opts.provider },
|
|
15887
|
+
...opts.location === void 0 ? {} : { location: opts.location },
|
|
15888
|
+
...opts.runId === void 0 ? {} : { runId: opts.runId },
|
|
15889
|
+
...opts.shape === void 0 ? {} : { shape: opts.shape },
|
|
15890
|
+
...opts.cursor === void 0 ? {} : { cursor: opts.cursor },
|
|
15891
|
+
...opts.limit === void 0 ? {} : { limit: opts.limit }
|
|
15892
|
+
});
|
|
15893
|
+
if (opts.format === "jsonl") {
|
|
15894
|
+
const page = shapedPage(response);
|
|
15895
|
+
emitJsonl([{
|
|
15896
|
+
kind: "measurement-property-evidence-header",
|
|
15897
|
+
shape: page.shape,
|
|
15898
|
+
property: response.property,
|
|
15899
|
+
queryClass: response.queryClass,
|
|
15900
|
+
measurement: response.measurement,
|
|
15901
|
+
totalEstimate: page.totalEstimate ?? null,
|
|
15902
|
+
nextCursor: page.nextCursor ?? null
|
|
15903
|
+
}]);
|
|
15904
|
+
emitJsonl(page.items);
|
|
15905
|
+
return;
|
|
15906
|
+
}
|
|
15907
|
+
if (opts.format === "json") {
|
|
15908
|
+
console.log(JSON.stringify(response, null, 2));
|
|
15909
|
+
return;
|
|
15910
|
+
}
|
|
15911
|
+
printMeasurementPropertyEvidence(response);
|
|
15912
|
+
}
|
|
15913
|
+
function signalText(signal) {
|
|
15914
|
+
if (signal === null) return "not measured";
|
|
15915
|
+
return signal ? "yes" : "no";
|
|
15916
|
+
}
|
|
15917
|
+
function printMeasurementPropertyEvidence(response) {
|
|
15918
|
+
const lines = [];
|
|
15919
|
+
lines.push(`${response.property.label} \u2014 ${response.queryClass} questions`);
|
|
15920
|
+
if (response.measurement.state === "not_measured") {
|
|
15921
|
+
lines.push("Not measured yet. Run a measurement to collect source evidence.");
|
|
15922
|
+
console.log(lines.join("\n"));
|
|
15923
|
+
return;
|
|
15924
|
+
}
|
|
15925
|
+
const page = shapedPage(response);
|
|
15926
|
+
const answerShape = page.shape === MeasurementEvidenceShapes.answers;
|
|
15927
|
+
lines.push(`Measurement: ${response.measurement.state}${response.measurement.displayedRunId ? ` \xB7 run ${response.measurement.displayedRunId}` : ""}`);
|
|
15928
|
+
if (page.items.length === 0) {
|
|
15929
|
+
lines.push(answerShape ? "No answers matched this Property in the displayed run." : "No source evidence matched this Property in the displayed run.");
|
|
15930
|
+
console.log(lines.join("\n"));
|
|
15931
|
+
return;
|
|
15932
|
+
}
|
|
15933
|
+
lines.push(`${page.items.length} of ${page.totalEstimate ?? page.items.length} ${answerShape ? "answers" : "evidence rows"}`);
|
|
15934
|
+
lines.push("");
|
|
15935
|
+
if (page.shape === MeasurementEvidenceShapes.answers) {
|
|
15936
|
+
lines.push(`${"Engine".padEnd(12)}${"Question".padEnd(40)}${"Mentioned".padEnd(15)}${"Cited".padEnd(8)}Sources`);
|
|
15937
|
+
for (const item of page.items) {
|
|
15938
|
+
lines.push(
|
|
15939
|
+
`${item.provider.padEnd(12)}${item.queryText.slice(0, 39).padEnd(40)}${signalText(item.mentioned).padEnd(15)}${signalText(item.cited).padEnd(8)}${item.sources.length}`
|
|
15940
|
+
);
|
|
15941
|
+
}
|
|
15942
|
+
} else {
|
|
15943
|
+
lines.push(`${"Match".padEnd(14)}${"Engine".padEnd(12)}${"Question".padEnd(40)}URL`);
|
|
15944
|
+
for (const item of page.items) {
|
|
15945
|
+
lines.push(`${item.classification.padEnd(14)}${item.provider.padEnd(12)}${item.queryText.slice(0, 39).padEnd(40)}${item.sourceUrl}`);
|
|
15946
|
+
}
|
|
15947
|
+
}
|
|
15948
|
+
if (page.nextCursor) lines.push(`
|
|
15949
|
+
More rows: --cursor ${page.nextCursor}`);
|
|
15950
|
+
console.log(lines.join("\n"));
|
|
15951
|
+
}
|
|
15759
15952
|
|
|
15760
15953
|
// src/cli-commands/measurement-plan.ts
|
|
15954
|
+
var QUERY_CLASSES = ["all", "branded", "non-brand"];
|
|
15955
|
+
var EVIDENCE_SHAPES = ["sources", "answers"];
|
|
15956
|
+
function queryClassOption(input) {
|
|
15957
|
+
const value = getString(input.values, "query-class");
|
|
15958
|
+
if (value === void 0) return void 0;
|
|
15959
|
+
const match = QUERY_CLASSES.find((candidate) => candidate === value);
|
|
15960
|
+
if (!match) throw usageError(`--query-class must be one of ${QUERY_CLASSES.join(", ")}`);
|
|
15961
|
+
return match;
|
|
15962
|
+
}
|
|
15963
|
+
function shapeOption(input) {
|
|
15964
|
+
const value = getString(input.values, "shape");
|
|
15965
|
+
if (value === void 0) return void 0;
|
|
15966
|
+
const match = EVIDENCE_SHAPES.find((candidate) => candidate === value);
|
|
15967
|
+
if (!match) throw usageError(`--shape must be one of ${EVIDENCE_SHAPES.join(", ")}`);
|
|
15968
|
+
return match;
|
|
15969
|
+
}
|
|
15970
|
+
function propertyScope(input, command, usage) {
|
|
15971
|
+
return {
|
|
15972
|
+
targetKey: requireStringOption(input, "target-key", { command, usage, message: "--target-key is required" }),
|
|
15973
|
+
queryClass: queryClassOption(input),
|
|
15974
|
+
provider: getString(input.values, "provider"),
|
|
15975
|
+
location: getString(input.values, "location"),
|
|
15976
|
+
runId: getString(input.values, "run-id"),
|
|
15977
|
+
format: input.format
|
|
15978
|
+
};
|
|
15979
|
+
}
|
|
15980
|
+
var PROPERTY_SCOPE_OPTIONS = {
|
|
15981
|
+
"target-key": stringOption(),
|
|
15982
|
+
"query-class": stringOption(),
|
|
15983
|
+
provider: stringOption(),
|
|
15984
|
+
location: stringOption(),
|
|
15985
|
+
"run-id": stringOption()
|
|
15986
|
+
};
|
|
15987
|
+
var ASSIGNMENT_AUDIENCE_OPTIONS = {
|
|
15988
|
+
group: multiStringOption(),
|
|
15989
|
+
"target-key": multiStringOption(),
|
|
15990
|
+
"all-properties": { type: "boolean" },
|
|
15991
|
+
"query-id": multiStringOption()
|
|
15992
|
+
};
|
|
15993
|
+
function assignmentAudience(input, command, usage) {
|
|
15994
|
+
const project = requireProject(input, command, usage);
|
|
15995
|
+
const groupKeys = getStringArray(input.values, "group")?.map((value) => value.trim()).filter(Boolean);
|
|
15996
|
+
const targetKeys = getStringArray(input.values, "target-key")?.map((value) => value.trim()).filter(Boolean);
|
|
15997
|
+
const queryIds = getStringArray(input.values, "query-id")?.map((value) => value.trim()).filter(Boolean) ?? [];
|
|
15998
|
+
const allProperties = getBoolean(input.values, "all-properties");
|
|
15999
|
+
if (queryIds.length === 0) throw usageError(`Error: at least one --query-id is required
|
|
16000
|
+
Usage: ${usage}`);
|
|
16001
|
+
if (allProperties && ((groupKeys?.length ?? 0) > 0 || (targetKeys?.length ?? 0) > 0)) {
|
|
16002
|
+
throw usageError(`Error: --all-properties cannot be combined with --group or --target-key
|
|
16003
|
+
Usage: ${usage}`);
|
|
16004
|
+
}
|
|
16005
|
+
if (!allProperties && (groupKeys?.length ?? 0) === 0 && (targetKeys?.length ?? 0) === 0) {
|
|
16006
|
+
throw usageError(`Error: select at least one --group, --target-key, or --all-properties
|
|
16007
|
+
Usage: ${usage}`);
|
|
16008
|
+
}
|
|
16009
|
+
return { project, options: { groupKeys, targetKeys, queryIds, allProperties } };
|
|
16010
|
+
}
|
|
15761
16011
|
var MEASUREMENT_PLAN_CLI_COMMANDS = [
|
|
15762
16012
|
{ path: ["measurement-plan", "show"], usage: "canonry measurement-plan show <project> [--revision N] [--format json]", options: { revision: stringOption() }, run: async (input) => {
|
|
15763
16013
|
const value = getString(input.values, "revision");
|
|
@@ -15778,6 +16028,85 @@ var MEASUREMENT_PLAN_CLI_COMMANDS = [
|
|
|
15778
16028
|
if (!stableKey) throw usageError("stable segment key is required");
|
|
15779
16029
|
return retireMeasurementPlanSegment(project, stableKey);
|
|
15780
16030
|
} },
|
|
16031
|
+
{
|
|
16032
|
+
path: ["measurement-plan", "assignments", "preview"],
|
|
16033
|
+
usage: "canonry measurement-plan assignments preview <project> [--group KEY ...] [--target-key KEY ... | --all-properties] --query-id ID [--query-id ID ...] [--format json]",
|
|
16034
|
+
options: ASSIGNMENT_AUDIENCE_OPTIONS,
|
|
16035
|
+
run: (input) => {
|
|
16036
|
+
const usage = "canonry measurement-plan assignments preview <project> [--group KEY ...] [--target-key KEY ... | --all-properties] --query-id ID [--query-id ID ...]";
|
|
16037
|
+
const { project, options } = assignmentAudience(input, "measurement-plan.assignments.preview", usage);
|
|
16038
|
+
return previewMeasurementPlanAssignments(project, options);
|
|
16039
|
+
}
|
|
16040
|
+
},
|
|
16041
|
+
{
|
|
16042
|
+
path: ["measurement-plan", "assignments", "apply"],
|
|
16043
|
+
usage: "canonry measurement-plan assignments apply <project> [--group KEY ...] [--target-key KEY ... | --all-properties] --query-id ID [--query-id ID ...] [--format json]",
|
|
16044
|
+
options: ASSIGNMENT_AUDIENCE_OPTIONS,
|
|
16045
|
+
run: (input) => {
|
|
16046
|
+
const usage = "canonry measurement-plan assignments apply <project> [--group KEY ...] [--target-key KEY ... | --all-properties] --query-id ID [--query-id ID ...]";
|
|
16047
|
+
const { project, options } = assignmentAudience(input, "measurement-plan.assignments.apply", usage);
|
|
16048
|
+
return applyMeasurementPlanAssignments(project, options);
|
|
16049
|
+
}
|
|
16050
|
+
},
|
|
16051
|
+
{
|
|
16052
|
+
path: ["measurement-plan", "assignments", "replace"],
|
|
16053
|
+
usage: "canonry measurement-plan assignments replace <project> [--group KEY ...] [--target-key KEY ... | --all-properties] --query-id ID [--query-id ID ...] --confirm [--format json]",
|
|
16054
|
+
options: { ...ASSIGNMENT_AUDIENCE_OPTIONS, confirm: { type: "boolean" } },
|
|
16055
|
+
run: (input) => {
|
|
16056
|
+
const usage = "canonry measurement-plan assignments replace <project> [--group KEY ...] [--target-key KEY ... | --all-properties] --query-id ID [--query-id ID ...] --confirm";
|
|
16057
|
+
if (!getBoolean(input.values, "confirm")) throw usageError(`Error: --confirm is required
|
|
16058
|
+
Usage: ${usage}`);
|
|
16059
|
+
const { project, options } = assignmentAudience(input, "measurement-plan.assignments.replace", usage);
|
|
16060
|
+
return replaceMeasurementPlanAssignments(project, options);
|
|
16061
|
+
}
|
|
16062
|
+
},
|
|
16063
|
+
{
|
|
16064
|
+
path: ["measurement-plan", "groups", "preview"],
|
|
16065
|
+
usage: "canonry measurement-plan groups preview <project> <csv|-> [--format json]",
|
|
16066
|
+
run: (input) => {
|
|
16067
|
+
const usage = "canonry measurement-plan groups preview <project> <csv|->";
|
|
16068
|
+
const project = requireProject(input, "measurement-plan.groups.preview", usage);
|
|
16069
|
+
const source = input.positionals[1];
|
|
16070
|
+
if (!source) throw usageError(`Error: CSV file path or - is required
|
|
16071
|
+
Usage: ${usage}`);
|
|
16072
|
+
return previewMeasurementPlanGroups(project, source);
|
|
16073
|
+
}
|
|
16074
|
+
},
|
|
16075
|
+
{
|
|
16076
|
+
path: ["measurement-plan", "groups", "apply"],
|
|
16077
|
+
usage: "canonry measurement-plan groups apply <project> <csv|-> --confirm [--accept-row N ... | --accept-all-matched] [--acknowledge-skipped] [--format json]",
|
|
16078
|
+
options: {
|
|
16079
|
+
confirm: { type: "boolean" },
|
|
16080
|
+
"accept-row": multiStringOption(),
|
|
16081
|
+
"accept-all-matched": { type: "boolean" },
|
|
16082
|
+
"acknowledge-skipped": { type: "boolean" }
|
|
16083
|
+
},
|
|
16084
|
+
run: (input) => {
|
|
16085
|
+
const usage = "canonry measurement-plan groups apply <project> <csv|-> --confirm [--accept-row N ... | --accept-all-matched] [--acknowledge-skipped]";
|
|
16086
|
+
const project = requireProject(input, "measurement-plan.groups.apply", usage);
|
|
16087
|
+
const source = input.positionals[1];
|
|
16088
|
+
if (!source) throw usageError(`Error: CSV file path or - is required
|
|
16089
|
+
Usage: ${usage}`);
|
|
16090
|
+
if (!getBoolean(input.values, "confirm")) throw usageError(`Error: --confirm is required
|
|
16091
|
+
Usage: ${usage}`);
|
|
16092
|
+
const acceptAllMatched = getBoolean(input.values, "accept-all-matched");
|
|
16093
|
+
const rowValues = getStringArray(input.values, "accept-row") ?? [];
|
|
16094
|
+
if (acceptAllMatched === rowValues.length > 0) {
|
|
16095
|
+
throw usageError(`Error: choose exactly one of --accept-row or --accept-all-matched
|
|
16096
|
+
Usage: ${usage}`);
|
|
16097
|
+
}
|
|
16098
|
+
const acceptedRows = rowValues.map((value) => Number(value));
|
|
16099
|
+
if (acceptedRows.some((row) => !Number.isSafeInteger(row) || row < 1)) {
|
|
16100
|
+
throw usageError(`Error: --accept-row must be a positive integer
|
|
16101
|
+
Usage: ${usage}`);
|
|
16102
|
+
}
|
|
16103
|
+
return applyMeasurementPlanGroups(project, source, {
|
|
16104
|
+
acceptedRows,
|
|
16105
|
+
acceptAllMatched,
|
|
16106
|
+
acknowledgeSkipped: getBoolean(input.values, "acknowledge-skipped")
|
|
16107
|
+
});
|
|
16108
|
+
}
|
|
16109
|
+
},
|
|
15781
16110
|
{
|
|
15782
16111
|
path: ["measurement-plan", "discover"],
|
|
15783
16112
|
usage: "canonry measurement-plan discover <project> --sitemap-url <url> --rule <yaml|json|-> [--max-urls N] [--format json]",
|
|
@@ -15816,6 +16145,37 @@ var MEASUREMENT_PLAN_CLI_COMMANDS = [
|
|
|
15816
16145
|
}
|
|
15817
16146
|
return showMeasurementReport(project, revision);
|
|
15818
16147
|
}
|
|
16148
|
+
},
|
|
16149
|
+
{
|
|
16150
|
+
path: ["measurement-plan", "property"],
|
|
16151
|
+
usage: "canonry measurement-plan property <project> --target-key <key> [--query-class all|branded|non-brand] [--provider <p>] [--location <l>] [--run-id <id>] [--format json]",
|
|
16152
|
+
options: PROPERTY_SCOPE_OPTIONS,
|
|
16153
|
+
run: (input) => {
|
|
16154
|
+
const usage = "canonry measurement-plan property <project> --target-key <key>";
|
|
16155
|
+
const project = requireProject(input, "measurement-plan.property", usage);
|
|
16156
|
+
return showMeasurementProperty(project, propertyScope(input, "measurement-plan.property", usage));
|
|
16157
|
+
}
|
|
16158
|
+
},
|
|
16159
|
+
{
|
|
16160
|
+
path: ["measurement-plan", "property-evidence"],
|
|
16161
|
+
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]",
|
|
16162
|
+
options: { ...PROPERTY_SCOPE_OPTIONS, shape: stringOption(), cursor: stringOption(), limit: stringOption() },
|
|
16163
|
+
run: (input) => {
|
|
16164
|
+
const usage = "canonry measurement-plan property-evidence <project> --target-key <key>";
|
|
16165
|
+
const project = requireProject(input, "measurement-plan.property-evidence", usage);
|
|
16166
|
+
const limitValue = getString(input.values, "limit");
|
|
16167
|
+
const limit = limitValue === void 0 ? void 0 : Number(limitValue);
|
|
16168
|
+
if (limit !== void 0 && (!Number.isInteger(limit) || limit < 1 || limit > 100)) {
|
|
16169
|
+
throw usageError("--limit must be an integer from 1 to 100");
|
|
16170
|
+
}
|
|
16171
|
+
const shape = shapeOption(input);
|
|
16172
|
+
return showMeasurementPropertyEvidence(project, {
|
|
16173
|
+
...propertyScope(input, "measurement-plan.property-evidence", usage),
|
|
16174
|
+
...shape === void 0 ? {} : { shape },
|
|
16175
|
+
cursor: getString(input.values, "cursor"),
|
|
16176
|
+
...limit === void 0 ? {} : { limit }
|
|
16177
|
+
});
|
|
16178
|
+
}
|
|
15819
16179
|
}
|
|
15820
16180
|
];
|
|
15821
16181
|
|
package/dist/index.js
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import {
|
|
2
2
|
createServer
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-ZDYS24LW.js";
|
|
4
4
|
import {
|
|
5
5
|
loadConfig
|
|
6
|
-
} from "./chunk-
|
|
7
|
-
import "./chunk-
|
|
8
|
-
import "./chunk-
|
|
6
|
+
} from "./chunk-4BL24FQA.js";
|
|
7
|
+
import "./chunk-DRDNHYIF.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-4BL24FQA.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",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@canonry/canonry",
|
|
3
|
-
"version": "4.
|
|
3
|
+
"version": "4.147.0",
|
|
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",
|
|
@@ -41,6 +41,7 @@
|
|
|
41
41
|
"dependencies": {
|
|
42
42
|
"@ainyc/aeo-audit": "4.0.1",
|
|
43
43
|
"@anthropic-ai/sdk": "^0.91.1",
|
|
44
|
+
"@fastify/rate-limit": "^11.2.0",
|
|
44
45
|
"@fastify/static": "^9.1.1",
|
|
45
46
|
"@google/genai": "^1.46.0",
|
|
46
47
|
"@mariozechner/pi-agent-core": "0.67.6",
|
|
@@ -66,26 +67,26 @@
|
|
|
66
67
|
"tsup": "^8.5.1",
|
|
67
68
|
"tsx": "^4.19.0",
|
|
68
69
|
"@ainyc/canonry-api-client": "0.0.0",
|
|
69
|
-
"@ainyc/canonry-api-routes": "0.0.0",
|
|
70
70
|
"@ainyc/canonry-config": "0.0.0",
|
|
71
|
-
"@ainyc/canonry-
|
|
71
|
+
"@ainyc/canonry-api-routes": "0.0.0",
|
|
72
72
|
"@ainyc/canonry-db": "0.0.0",
|
|
73
|
-
"@ainyc/canonry-
|
|
73
|
+
"@ainyc/canonry-contracts": "0.0.0",
|
|
74
74
|
"@ainyc/canonry-integration-bing": "0.0.0",
|
|
75
|
-
"@ainyc/canonry-integration-
|
|
75
|
+
"@ainyc/canonry-integration-openai-ads": "0.0.0",
|
|
76
|
+
"@ainyc/canonry-integration-cloud-run": "0.0.0",
|
|
76
77
|
"@ainyc/canonry-integration-google": "0.0.0",
|
|
78
|
+
"@ainyc/canonry-integration-commoncrawl": "0.0.0",
|
|
77
79
|
"@ainyc/canonry-integration-google-business-profile": "0.0.0",
|
|
78
80
|
"@ainyc/canonry-integration-google-places": "0.0.0",
|
|
79
|
-
"@ainyc/canonry-integration-
|
|
81
|
+
"@ainyc/canonry-integration-traffic": "0.0.0",
|
|
80
82
|
"@ainyc/canonry-integration-wordpress": "0.0.0",
|
|
81
83
|
"@ainyc/canonry-intelligence": "0.0.0",
|
|
82
|
-
"@ainyc/canonry-integration-traffic": "0.0.0",
|
|
83
84
|
"@ainyc/canonry-provider-cdp": "0.0.0",
|
|
84
85
|
"@ainyc/canonry-provider-claude": "0.0.0",
|
|
85
|
-
"@ainyc/canonry-provider-local": "0.0.0",
|
|
86
86
|
"@ainyc/canonry-provider-gemini": "0.0.0",
|
|
87
|
-
"@ainyc/canonry-provider-
|
|
88
|
-
"@ainyc/canonry-provider-openai": "0.0.0"
|
|
87
|
+
"@ainyc/canonry-provider-local": "0.0.0",
|
|
88
|
+
"@ainyc/canonry-provider-openai": "0.0.0",
|
|
89
|
+
"@ainyc/canonry-provider-perplexity": "0.0.0"
|
|
89
90
|
},
|
|
90
91
|
"scripts": {
|
|
91
92
|
"build": "tsx scripts/copy-agent-assets.ts && tsup && tsx build-web.ts",
|