@canonry/canonry 7.4.0 → 7.5.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-DIL5oTHF.js → AuditHistoryPanel-B5aLMnWE.js} +1 -1
- package/assets/assets/{BacklinksPage-BpCURZh8.js → BacklinksPage-Biq1jrqe.js} +1 -1
- package/assets/assets/{HistoryPage-TPbexxzA.js → HistoryPage-CGGkAgnz.js} +1 -1
- package/assets/assets/MeasurementPropertyPage-BwyWGGBg.js +1 -0
- package/assets/assets/ProjectPage-DEnKyD3e.js +8 -0
- package/assets/assets/{RunsPage-Dhu7Qe7B.js → RunsPage-DNBn0Rau.js} +1 -1
- package/assets/assets/{SettingsPage-BCG1QJ07.js → SettingsPage-D3m-BLuf.js} +1 -1
- package/assets/assets/{SiteHealthSection-BXueYSiu.js → SiteHealthSection-CPMu1l-l.js} +3 -3
- package/assets/assets/{TrafficPage-ua9wsccA.js → TrafficPage-BCK_V__i.js} +2 -2
- package/assets/assets/{TrafficSourceDetailPage-pwATnkp8.js → TrafficSourceDetailPage-DaCehUm8.js} +1 -1
- package/assets/assets/{extract-error-message-DJfNdKqh.js → extract-error-message-CqBLzzuR.js} +1 -1
- package/assets/assets/{index-DvWWyhGp.js → index-C2X_UARl.js} +15 -15
- package/assets/assets/{react-sigma_core.esm.min-DnbWY5j_.js → react-sigma_core.esm.min-BvO4SZKT.js} +1 -1
- package/assets/assets/v2-overview-adapter-CgDChBa5.js +1 -0
- package/assets/index.html +1 -1
- package/dist/{chunk-TNLOOXUP.js → chunk-56YOI7QX.js} +2 -2
- package/dist/{chunk-GEKMHZS2.js → chunk-HAWCV4SU.js} +10 -10
- package/dist/{chunk-SWSWCUHS.js → chunk-JTQ4KFIR.js} +64 -31
- package/dist/{chunk-ZP6GF32R.js → chunk-KJIXDPYH.js} +3 -3
- package/dist/{chunk-PXRUWG75.js → chunk-RVM6QJQT.js} +75 -8
- package/dist/{chunk-JU6TPMCJ.js → chunk-VVEMJCC6.js} +2 -2
- package/dist/{chunk-XFVJ6QVE.js → chunk-Y7K5NMNV.js} +2 -2
- package/dist/cli.js +26 -15
- package/dist/{demo-server-INMOE4BA.js → demo-server-V3DDLXND.js} +4 -4
- package/dist/index.js +6 -6
- package/dist/{intelligence-service-IBUS2IND.js → intelligence-service-MZVPWIXL.js} +2 -2
- package/dist/mcp.js +4 -4
- package/package.json +12 -12
- package/assets/assets/MeasurementPropertyPage-H991GW9h.js +0 -1
- package/assets/assets/ProjectPage-l1NAl-9k.js +0 -8
- package/assets/assets/v2-overview-adapter-BIOvZAlo.js +0 -1
|
@@ -3637,8 +3637,18 @@ var measurementMetricValueSchema = z6.discriminatedUnion("state", [
|
|
|
3637
3637
|
* Mention coverage only: answers left out of numerator and denominator
|
|
3638
3638
|
* because they could not be tied to one Property. Absent means none.
|
|
3639
3639
|
*/
|
|
3640
|
-
unattributed: z6.number().int().positive().optional()
|
|
3641
|
-
|
|
3640
|
+
unattributed: z6.number().int().positive().optional(),
|
|
3641
|
+
/**
|
|
3642
|
+
* Citation coverage only: saved answers left out of numerator and
|
|
3643
|
+
* denominator because their source-link capture was incomplete. A link
|
|
3644
|
+
* such an answer did capture is not counted either. Absent means none.
|
|
3645
|
+
*/
|
|
3646
|
+
unchecked: z6.number().int().positive().optional()
|
|
3647
|
+
}).strict().superRefine((value, ctx) => {
|
|
3648
|
+
if (value.unattributed !== void 0 && value.unchecked !== void 0) {
|
|
3649
|
+
ctx.addIssue({ code: "custom", path: ["unchecked"], message: "A metric reads one signal: unattributed (mention) and unchecked (citation) cannot share it" });
|
|
3650
|
+
}
|
|
3651
|
+
}),
|
|
3642
3652
|
z6.object({
|
|
3643
3653
|
state: z6.literal("unavailable"),
|
|
3644
3654
|
reason: measurementMetricUnavailableReasonSchema
|
|
@@ -8220,7 +8230,22 @@ var visibilityReportRateSchema = z20.object({
|
|
|
8220
8230
|
* absent means none were. When every answer is unattributable the rate is
|
|
8221
8231
|
* unavailable with reason `identity-ambiguous` instead.
|
|
8222
8232
|
*/
|
|
8223
|
-
unattributed: z20.number().int().positive().optional()
|
|
8233
|
+
unattributed: z20.number().int().positive().optional(),
|
|
8234
|
+
/**
|
|
8235
|
+
* Saved answers left out of a citation rate because their source-link
|
|
8236
|
+
* capture was incomplete (`citationComplete: false`). They leave the
|
|
8237
|
+
* numerator AND the denominator: a link that was never read is not counted as
|
|
8238
|
+
* not cited, and a link that was read on such an answer is not counted as
|
|
8239
|
+
* cited either, since counting only those positives would bias the rate up.
|
|
8240
|
+
* Present only on an available rate that left at least one answer out;
|
|
8241
|
+
* absent means none were. When every answer is unchecked the rate is
|
|
8242
|
+
* unavailable with reason `evidence-incomplete`, and a missing answer (no
|
|
8243
|
+
* saved observation) still withholds the rate that way. Never beside
|
|
8244
|
+
* `unattributed`: one rate reads one signal. A Simple project's citation
|
|
8245
|
+
* state comes from stored cited domains, not URL capture, so its rates never
|
|
8246
|
+
* carry this field.
|
|
8247
|
+
*/
|
|
8248
|
+
unchecked: z20.number().int().positive().optional()
|
|
8224
8249
|
}).strict().superRefine((value, ctx) => {
|
|
8225
8250
|
const unavailable = value.numerator === null || value.denominator === null || value.rate === null;
|
|
8226
8251
|
if (unavailable) {
|
|
@@ -8230,11 +8255,17 @@ var visibilityReportRateSchema = z20.object({
|
|
|
8230
8255
|
if (value.unattributed !== void 0) {
|
|
8231
8256
|
ctx.addIssue({ code: z20.ZodIssueCode.custom, path: ["unattributed"], message: "Only an available rate can leave answers out" });
|
|
8232
8257
|
}
|
|
8258
|
+
if (value.unchecked !== void 0) {
|
|
8259
|
+
ctx.addIssue({ code: z20.ZodIssueCode.custom, path: ["unchecked"], message: "Only an available rate can leave answers out" });
|
|
8260
|
+
}
|
|
8233
8261
|
return;
|
|
8234
8262
|
}
|
|
8235
8263
|
if (value.reason !== void 0) {
|
|
8236
8264
|
ctx.addIssue({ code: z20.ZodIssueCode.custom, message: "Available rates cannot carry a reason" });
|
|
8237
8265
|
}
|
|
8266
|
+
if (value.unattributed !== void 0 && value.unchecked !== void 0) {
|
|
8267
|
+
ctx.addIssue({ code: z20.ZodIssueCode.custom, path: ["unchecked"], message: "A rate reads one signal: unattributed (mention) and unchecked (citation) cannot share it" });
|
|
8268
|
+
}
|
|
8238
8269
|
const { numerator, denominator } = value;
|
|
8239
8270
|
if (denominator === null || numerator === null) return;
|
|
8240
8271
|
if (denominator === 0) {
|
|
@@ -8885,7 +8916,8 @@ var measurementRateSchema = z22.union([
|
|
|
8885
8916
|
numerator: z22.number().int().nonnegative(),
|
|
8886
8917
|
denominator: z22.number().int().positive(),
|
|
8887
8918
|
rate: fraction(z22.number().min(0).max(1)),
|
|
8888
|
-
unattributed: z22.number().int().positive().optional()
|
|
8919
|
+
unattributed: z22.number().int().positive().optional(),
|
|
8920
|
+
unchecked: z22.number().int().positive().optional()
|
|
8889
8921
|
}).strict(),
|
|
8890
8922
|
z22.object({
|
|
8891
8923
|
numerator: z22.null(),
|
|
@@ -8897,6 +8929,9 @@ var measurementRateSchema = z22.union([
|
|
|
8897
8929
|
if (value.numerator !== null && value.numerator > value.denominator) {
|
|
8898
8930
|
ctx.addIssue({ code: "custom", path: ["numerator"], message: "Rate numerator cannot exceed denominator" });
|
|
8899
8931
|
}
|
|
8932
|
+
if (value.numerator !== null && value.unattributed !== void 0 && value.unchecked !== void 0) {
|
|
8933
|
+
ctx.addIssue({ code: "custom", path: ["unchecked"], message: "A rate reads one signal: unattributed (mention) and unchecked (citation) cannot share it" });
|
|
8934
|
+
}
|
|
8900
8935
|
});
|
|
8901
8936
|
var normalizedMeasurementProviderSchema = z22.string().trim().min(1).overwrite((value) => value.toLocaleLowerCase("en"));
|
|
8902
8937
|
var measurementExpectedSlotV1Schema = z22.object({
|
|
@@ -19316,6 +19351,7 @@ function serializeForInlineScript(value) {
|
|
|
19316
19351
|
// ../contracts/src/provider-errors.ts
|
|
19317
19352
|
var PROVIDER_ERROR_PRIORITY = [
|
|
19318
19353
|
"PROVIDER_AUTH",
|
|
19354
|
+
"PROVIDER_BILLING",
|
|
19319
19355
|
"RATE_LIMITED",
|
|
19320
19356
|
"PROVIDER_UNAVAILABLE",
|
|
19321
19357
|
"TIMEOUT",
|
|
@@ -19324,13 +19360,16 @@ var PROVIDER_ERROR_PRIORITY = [
|
|
|
19324
19360
|
"UNKNOWN"
|
|
19325
19361
|
];
|
|
19326
19362
|
function classifyProviderErrorMessage(message) {
|
|
19327
|
-
|
|
19363
|
+
const status = extractProviderHttpStatus(message);
|
|
19364
|
+
if (status === 401 || status === 403 || /unauthorized|forbidden|invalid[_ -]?api[_ -]?key|missing[_ -]?api[_ -]?key|api[_ -]?key[_ -]?(?:is[_ -]?)?(?:not[_ -]?valid|invalid|expired)|authentication/i.test(message)) {
|
|
19328
19365
|
return "PROVIDER_AUTH";
|
|
19329
19366
|
}
|
|
19330
|
-
if (
|
|
19367
|
+
if (status === 402 || /payment required|credit balance|insufficient[_ -]?(?:quota|credits?|balance|funds)/i.test(message) || /exceeded your current quota/i.test(message) && !/RESOURCE_EXHAUSTED/.test(message)) {
|
|
19368
|
+
return "PROVIDER_BILLING";
|
|
19369
|
+
}
|
|
19370
|
+
if (status === 429 || /rate[_ -]?limit|too many requests|quota[_ -]?exceeded/i.test(message)) {
|
|
19331
19371
|
return "RATE_LIMITED";
|
|
19332
19372
|
}
|
|
19333
|
-
const status = extractProviderHttpStatus(message);
|
|
19334
19373
|
if (status !== void 0 && status >= 500 || /overloaded|service unavailable|bad gateway|internal server error/i.test(message)) {
|
|
19335
19374
|
return "PROVIDER_UNAVAILABLE";
|
|
19336
19375
|
}
|
|
@@ -20420,6 +20459,32 @@ function unattributedAnswersLabel(value) {
|
|
|
20420
20459
|
if (value.unattributed === void 0 || value.unattributed <= 0) return null;
|
|
20421
20460
|
return `${value.unattributed} of ${value.denominator + value.unattributed} answers could not be tied to one property`;
|
|
20422
20461
|
}
|
|
20462
|
+
function uncheckedSourcesLabel(value) {
|
|
20463
|
+
if (value.denominator === null || value.denominator === void 0) return null;
|
|
20464
|
+
if (value.unchecked === void 0 || value.unchecked <= 0) return null;
|
|
20465
|
+
const total = value.denominator + value.unchecked;
|
|
20466
|
+
return `${value.unchecked} of ${total} ${total === 1 ? "answer" : "answers"} had sources that could not be checked`;
|
|
20467
|
+
}
|
|
20468
|
+
|
|
20469
|
+
// ../contracts/src/coverage-rate.ts
|
|
20470
|
+
function assertCount(name, value) {
|
|
20471
|
+
if (!Number.isInteger(value) || value < 0) {
|
|
20472
|
+
throw new RangeError(`${name} must be a non-negative integer, got ${value}`);
|
|
20473
|
+
}
|
|
20474
|
+
}
|
|
20475
|
+
function rateOverChecked(numerator, answers, excluded, field) {
|
|
20476
|
+
assertCount("numerator", numerator);
|
|
20477
|
+
assertCount("answers", answers);
|
|
20478
|
+
assertCount("excluded", excluded);
|
|
20479
|
+
if (excluded > answers) throw new RangeError(`excluded (${excluded}) cannot exceed answers (${answers})`);
|
|
20480
|
+
const denominator = answers - excluded;
|
|
20481
|
+
if (numerator > denominator) {
|
|
20482
|
+
throw new RangeError(`numerator (${numerator}) cannot exceed the ${denominator} checked answers`);
|
|
20483
|
+
}
|
|
20484
|
+
if (denominator === 0) return null;
|
|
20485
|
+
const rate2 = { numerator, denominator, rate: numerator / denominator };
|
|
20486
|
+
return excluded === 0 ? rate2 : { ...rate2, [field]: excluded };
|
|
20487
|
+
}
|
|
20423
20488
|
|
|
20424
20489
|
export {
|
|
20425
20490
|
__export,
|
|
@@ -21374,5 +21439,7 @@ export {
|
|
|
21374
21439
|
parseTrafficAnalyticsPeriod,
|
|
21375
21440
|
trafficAnalyticsResponseSchema,
|
|
21376
21441
|
UNATTRIBUTED_MENTION_REASON,
|
|
21377
|
-
unattributedAnswersLabel
|
|
21442
|
+
unattributedAnswersLabel,
|
|
21443
|
+
uncheckedSourcesLabel,
|
|
21444
|
+
rateOverChecked
|
|
21378
21445
|
};
|
|
@@ -135,7 +135,7 @@ import {
|
|
|
135
135
|
trafficSeriesGranularitySchema,
|
|
136
136
|
visibilityCompareSelectionSchema,
|
|
137
137
|
visibilityReportRequestSchema
|
|
138
|
-
} from "./chunk-
|
|
138
|
+
} from "./chunk-RVM6QJQT.js";
|
|
139
139
|
|
|
140
140
|
// src/cli-error.ts
|
|
141
141
|
function isMachineFormat(format) {
|
|
@@ -2911,7 +2911,7 @@ var canonryMcpTools = [
|
|
|
2911
2911
|
defineTool({
|
|
2912
2912
|
name: "canonry_measurement_portfolio_summary",
|
|
2913
2913
|
title: "Summarize measured Properties",
|
|
2914
|
-
description: "Start here for best and worst Properties. One call returns the weakest Properties, the names answers wrote instead of them, and the domains engines cited for them. Defaults to non-brand queries; state the returned queryClass and never pool branded with non-brand. Returns at most 4 Property rows per list, the most that fit one result; a larger limit is lowered and limitNote says so. For other rows pass groupKey (one metro's weakest), or page canonry_measurement_overview. Mention (answer text names the Property) and citation (a source URL on its page) are separate: report each as numerator/denominator, with any unattributed count beside mention. Denominators count answers, one per query per engine (queries x engines = answers). Group Properties only by each row's metro and submarkets, never by label. namedInsteadInAnswerText lists names written in the answer text of answers that neither named nor cited the Property, counted by answer: they are not citations, and namedInsteadInAnswerTextTotal counts distinct names, not answers. citedDomains and weakestAnswerSources count answers citing each domain, every engine included; weakestAnswerSources pools the weakest rows plus every tied Property, each answer once, and its domainTotal counts distinct domains, not citations. weakestAnswerSources.ownDomainAnswers counts those answers that cite any of your own domains. A Property's citationCoverage counts only answers citing that Property's own page, so 0% citation does not mean your domain went uncited; use ownDomainAnswers for that. When tiedAtWeakest is set, tiedAtWeakest.count Properties share the weakest rates and the rows are the first of them by name, not a rank: report the count, tiedAtWeakest.byMetro (tied Properties per metro over the whole tie; a Property in two metros counts in both) and tiedAtWeakest.namedInstead (names written instead across the whole tie, counted by distinct answer; namedInsteadTotal is distinct names), and call the rows examples. mentionRanking.strongest/.weakest rank every Property with an available mention rate; .excluded lists the rest with reasons. markets lists every market at one level, worst-first (every metro, or a groupKey's submarkets), whatever the limit. Markets may share Properties and never sum to portfolio totals. Reads stored data only; never starts provider work.",
|
|
2914
|
+
description: "Start here for best and worst Properties. One call returns the weakest Properties, the names answers wrote instead of them, and the domains engines cited for them. Defaults to non-brand queries; state the returned queryClass and never pool branded with non-brand. Returns at most 4 Property rows per list, the most that fit one result; a larger limit is lowered and limitNote says so. For other rows pass groupKey (one metro's weakest), or page canonry_measurement_overview. Mention (answer text names the Property) and citation (a source URL on its page) are separate: report each as numerator/denominator, with any unattributed count beside mention and any unchecked count beside citation (saved answers whose source capture was incomplete; they are in neither side). Denominators count answers, one per query per engine (queries x engines = answers, less any unattributed or unchecked). Group Properties only by each row's metro and submarkets, never by label. namedInsteadInAnswerText lists names written in the answer text of answers that neither named nor cited the Property, counted by answer: they are not citations, and namedInsteadInAnswerTextTotal counts distinct names, not answers. citedDomains and weakestAnswerSources count answers citing each domain, every engine included; weakestAnswerSources pools the weakest rows plus every tied Property, each answer once, and its domainTotal counts distinct domains, not citations. weakestAnswerSources.ownDomainAnswers counts those answers that cite any of your own domains. A Property's citationCoverage counts only answers citing that Property's own page, so 0% citation does not mean your domain went uncited; use ownDomainAnswers for that. When tiedAtWeakest is set, tiedAtWeakest.count Properties share the weakest rates and the rows are the first of them by name, not a rank: report the count, tiedAtWeakest.byMetro (tied Properties per metro over the whole tie; a Property in two metros counts in both) and tiedAtWeakest.namedInstead (names written instead across the whole tie, counted by distinct answer; namedInsteadTotal is distinct names), and call the rows examples. mentionRanking.strongest/.weakest rank every Property with an available mention rate; .excluded lists the rest with reasons. markets lists every market at one level, worst-first (every metro, or a groupKey's submarkets), whatever the limit. Markets may share Properties and never sum to portfolio totals. Reads stored data only; never starts provider work.",
|
|
2915
2915
|
access: "read",
|
|
2916
2916
|
tier: "monitoring",
|
|
2917
2917
|
inputSchema: measurementPortfolioSummaryInputSchema,
|
|
@@ -5,7 +5,7 @@ import {
|
|
|
5
5
|
siteCrawlGraphNodes,
|
|
6
6
|
siteCrawlPages,
|
|
7
7
|
siteCrawlSnapshots
|
|
8
|
-
} from "./chunk-
|
|
8
|
+
} from "./chunk-JTQ4KFIR.js";
|
|
9
9
|
import {
|
|
10
10
|
SITE_CRAWL_GRAPH_MAX_EDGES,
|
|
11
11
|
SITE_CRAWL_GRAPH_MAX_NODES,
|
|
@@ -13,7 +13,7 @@ import {
|
|
|
13
13
|
TEMPLATE_LINK_RATIO_THRESHOLD,
|
|
14
14
|
factorStatusFromScore,
|
|
15
15
|
roundPreservingTotal
|
|
16
|
-
} from "./chunk-
|
|
16
|
+
} from "./chunk-RVM6QJQT.js";
|
|
17
17
|
|
|
18
18
|
// src/site-audit-factors.ts
|
|
19
19
|
function recordedSharePct(factor) {
|
package/dist/cli.js
CHANGED
|
@@ -32,11 +32,11 @@ import {
|
|
|
32
32
|
trackCliCommandFinished,
|
|
33
33
|
trackEvent,
|
|
34
34
|
waitForServerRuntimeStartup
|
|
35
|
-
} from "./chunk-
|
|
35
|
+
} from "./chunk-HAWCV4SU.js";
|
|
36
36
|
import {
|
|
37
37
|
autoSyncSkills,
|
|
38
38
|
formatAutoSyncNotice
|
|
39
|
-
} from "./chunk-
|
|
39
|
+
} from "./chunk-KJIXDPYH.js";
|
|
40
40
|
import {
|
|
41
41
|
configExists,
|
|
42
42
|
createApiClient,
|
|
@@ -53,13 +53,13 @@ import {
|
|
|
53
53
|
saveConfig,
|
|
54
54
|
saveConfigPatch,
|
|
55
55
|
shouldPrintServeSkillsNudge
|
|
56
|
-
} from "./chunk-
|
|
56
|
+
} from "./chunk-56YOI7QX.js";
|
|
57
57
|
import {
|
|
58
58
|
DEFAULT_DEMO_TRUSTED_PROXIES,
|
|
59
59
|
trustedProxiesProblem,
|
|
60
60
|
trustedProxyProblem
|
|
61
61
|
} from "./chunk-RB2F4D3Z.js";
|
|
62
|
-
import "./chunk-
|
|
62
|
+
import "./chunk-Y7K5NMNV.js";
|
|
63
63
|
import {
|
|
64
64
|
CliError,
|
|
65
65
|
EXIT_SYSTEM_ERROR,
|
|
@@ -71,7 +71,7 @@ import {
|
|
|
71
71
|
runMeasurementDraftAction,
|
|
72
72
|
systemError,
|
|
73
73
|
usageError
|
|
74
|
-
} from "./chunk-
|
|
74
|
+
} from "./chunk-VVEMJCC6.js";
|
|
75
75
|
import {
|
|
76
76
|
CLOUDFLARE_WORKER_BINDINGS,
|
|
77
77
|
CLOUDFLARE_WORKER_GENERATED_MARKER,
|
|
@@ -100,7 +100,7 @@ import {
|
|
|
100
100
|
querySnapshots,
|
|
101
101
|
rawEventSamples,
|
|
102
102
|
runs
|
|
103
|
-
} from "./chunk-
|
|
103
|
+
} from "./chunk-JTQ4KFIR.js";
|
|
104
104
|
import {
|
|
105
105
|
AdsDeliverySnapshotStatuses,
|
|
106
106
|
AdsHistoricalCampaignRollupStatuses,
|
|
@@ -224,10 +224,11 @@ import {
|
|
|
224
224
|
siteAuditPageBudgetSchema,
|
|
225
225
|
snapshotProviderModeSchema,
|
|
226
226
|
unattributedAnswersLabel,
|
|
227
|
+
uncheckedSourcesLabel,
|
|
227
228
|
visibilityCompareSelectionSchema,
|
|
228
229
|
visibilityReportRequestSchema,
|
|
229
230
|
winnabilityClassSchema
|
|
230
|
-
} from "./chunk-
|
|
231
|
+
} from "./chunk-RVM6QJQT.js";
|
|
231
232
|
|
|
232
233
|
// src/cli.ts
|
|
233
234
|
import { pathToFileURL } from "url";
|
|
@@ -777,7 +778,7 @@ function parseDemoTrustedProxies(values) {
|
|
|
777
778
|
async function demoCommand(options) {
|
|
778
779
|
const { host, port } = parseDemoListenOptions(options);
|
|
779
780
|
const trustProxy = parseDemoTrustedProxies(options.trustProxy);
|
|
780
|
-
const { createDemoServer } = await import("./demo-server-
|
|
781
|
+
const { createDemoServer } = await import("./demo-server-V3DDLXND.js");
|
|
781
782
|
const app = await createDemoServer({ trustProxy });
|
|
782
783
|
let stopping = false;
|
|
783
784
|
const stop = () => {
|
|
@@ -1191,7 +1192,7 @@ No DB writes performed. Re-run without --dry-run to apply.`);
|
|
|
1191
1192
|
}
|
|
1192
1193
|
}
|
|
1193
1194
|
async function backfillInsightsCommand(project2, opts) {
|
|
1194
|
-
const { IntelligenceService } = await import("./intelligence-service-
|
|
1195
|
+
const { IntelligenceService } = await import("./intelligence-service-MZVPWIXL.js");
|
|
1195
1196
|
const config = loadConfig();
|
|
1196
1197
|
const db = createClient(config.database);
|
|
1197
1198
|
migrate(db);
|
|
@@ -11988,6 +11989,12 @@ var METRIC_REASONS = {
|
|
|
11988
11989
|
function unattributedText(metric) {
|
|
11989
11990
|
return metric.state === "available" ? unattributedAnswersLabel(metric) : null;
|
|
11990
11991
|
}
|
|
11992
|
+
function uncheckedText(metric) {
|
|
11993
|
+
return metric.state === "available" ? uncheckedSourcesLabel(metric) : null;
|
|
11994
|
+
}
|
|
11995
|
+
function metricWithNote(metric, note) {
|
|
11996
|
+
return `${metricText(metric)}${note ? ` \xB7 ${note}` : ""}`;
|
|
11997
|
+
}
|
|
11991
11998
|
function metricText(metric) {
|
|
11992
11999
|
if (metric.state === "unavailable") return METRIC_REASONS[metric.reason] ?? `not measured (${metric.reason})`;
|
|
11993
12000
|
const percent = formatPercent(metric.value);
|
|
@@ -12015,17 +12022,21 @@ function printMeasurementProperty(response) {
|
|
|
12015
12022
|
lines.push(`Measurement: ${response.measurement.state}${response.measurement.displayedRunId ? ` \xB7 run ${response.measurement.displayedRunId}` : ""}`);
|
|
12016
12023
|
lines.push("");
|
|
12017
12024
|
const mention = row ? row.mentionCoverage : response.metrics.mentionCoverage;
|
|
12018
|
-
const
|
|
12019
|
-
lines.push(`Mentioned ${
|
|
12020
|
-
lines.push(`Cited ${
|
|
12025
|
+
const citation = row ? row.citationCoverage : response.metrics.citationCoverage;
|
|
12026
|
+
lines.push(`Mentioned ${metricWithNote(mention, unattributedText(mention))}`);
|
|
12027
|
+
lines.push(`Cited ${metricWithNote(citation, uncheckedText(citation))}`);
|
|
12021
12028
|
if (row && row.flags > 0) lines.push(`Flagged ${row.flags} ${row.flags === 1 ? "result needs" : "results need"} review`);
|
|
12022
12029
|
if (row && row.providers.length > 0) {
|
|
12030
|
+
const engineWidth = 14;
|
|
12031
|
+
const mentionWidth = 34;
|
|
12023
12032
|
lines.push("");
|
|
12024
|
-
lines.push(`${"Engine".padEnd(
|
|
12033
|
+
lines.push(`${"Engine".padEnd(engineWidth)}${"Mentioned".padEnd(mentionWidth)}Cited`);
|
|
12025
12034
|
for (const provider of row.providers) {
|
|
12026
|
-
lines.push(`${provider.provider.padEnd(
|
|
12035
|
+
lines.push(`${provider.provider.padEnd(engineWidth)}${metricText(provider.mentionCoverage).padEnd(mentionWidth)}${metricText(provider.citationCoverage)}`);
|
|
12027
12036
|
const providerUnattributed = unattributedText(provider.mentionCoverage);
|
|
12028
|
-
if (providerUnattributed) lines.push(`${"".padEnd(
|
|
12037
|
+
if (providerUnattributed) lines.push(`${"".padEnd(engineWidth)}${providerUnattributed}`);
|
|
12038
|
+
const providerUnchecked = uncheckedText(provider.citationCoverage);
|
|
12039
|
+
if (providerUnchecked) lines.push(`${"".padEnd(engineWidth + mentionWidth)}${providerUnchecked}`);
|
|
12029
12040
|
}
|
|
12030
12041
|
}
|
|
12031
12042
|
console.log(lines.join("\n"));
|
|
@@ -5,11 +5,11 @@ import {
|
|
|
5
5
|
computeFactorAverages,
|
|
6
6
|
layoutSiteCrawlGraphInput,
|
|
7
7
|
persistSiteCrawlGraphLayout
|
|
8
|
-
} from "./chunk-
|
|
8
|
+
} from "./chunk-Y7K5NMNV.js";
|
|
9
9
|
import {
|
|
10
10
|
PACKAGE_VERSION,
|
|
11
11
|
canonryMcpTools
|
|
12
|
-
} from "./chunk-
|
|
12
|
+
} from "./chunk-VVEMJCC6.js";
|
|
13
13
|
import {
|
|
14
14
|
HISTORY_WINDOW_RUNS,
|
|
15
15
|
IntelligenceService,
|
|
@@ -83,7 +83,7 @@ import {
|
|
|
83
83
|
siteCrawlPages,
|
|
84
84
|
siteCrawlSnapshots,
|
|
85
85
|
trafficSources
|
|
86
|
-
} from "./chunk-
|
|
86
|
+
} from "./chunk-JTQ4KFIR.js";
|
|
87
87
|
import {
|
|
88
88
|
RunKinds,
|
|
89
89
|
SiteCrawlFetchStates,
|
|
@@ -112,7 +112,7 @@ import {
|
|
|
112
112
|
roundPreservingTotal,
|
|
113
113
|
siteAuditPageFactorSchema,
|
|
114
114
|
wilsonInterval
|
|
115
|
-
} from "./chunk-
|
|
115
|
+
} from "./chunk-RVM6QJQT.js";
|
|
116
116
|
|
|
117
117
|
// src/demo-server.ts
|
|
118
118
|
import { dirname, join as join2 } from "path";
|
package/dist/index.js
CHANGED
|
@@ -3,14 +3,14 @@ import {
|
|
|
3
3
|
createGoogleMarketingCredentialStore,
|
|
4
4
|
createGoogleMarketingRuntime,
|
|
5
5
|
createServer
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-HAWCV4SU.js";
|
|
7
7
|
import {
|
|
8
8
|
loadConfig
|
|
9
|
-
} from "./chunk-
|
|
10
|
-
import "./chunk-
|
|
11
|
-
import "./chunk-
|
|
12
|
-
import "./chunk-
|
|
13
|
-
import "./chunk-
|
|
9
|
+
} from "./chunk-56YOI7QX.js";
|
|
10
|
+
import "./chunk-Y7K5NMNV.js";
|
|
11
|
+
import "./chunk-VVEMJCC6.js";
|
|
12
|
+
import "./chunk-JTQ4KFIR.js";
|
|
13
|
+
import "./chunk-RVM6QJQT.js";
|
|
14
14
|
export {
|
|
15
15
|
GoogleMarketingRuntimeError,
|
|
16
16
|
createGoogleMarketingCredentialStore,
|
package/dist/mcp.js
CHANGED
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
import {
|
|
2
2
|
autoSyncSkills
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-KJIXDPYH.js";
|
|
4
4
|
import {
|
|
5
5
|
createApiClient,
|
|
6
6
|
createCanonryMcpServer
|
|
7
|
-
} from "./chunk-
|
|
8
|
-
import "./chunk-
|
|
7
|
+
} from "./chunk-56YOI7QX.js";
|
|
8
|
+
import "./chunk-VVEMJCC6.js";
|
|
9
9
|
import {
|
|
10
10
|
isReadOnlyKey,
|
|
11
11
|
updateCheckEnvOptOut
|
|
12
|
-
} from "./chunk-
|
|
12
|
+
} from "./chunk-RVM6QJQT.js";
|
|
13
13
|
|
|
14
14
|
// src/mcp/cli.ts
|
|
15
15
|
import { randomUUID } from "crypto";
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@canonry/canonry",
|
|
3
|
-
"version": "7.
|
|
3
|
+
"version": "7.5.1",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Self-hosted AI visibility (AEO) platform: track how ChatGPT, Claude, Gemini, and Perplexity cite your domain, join it with Search Console, GA4, server-side traffic, and paid media, and fix what you find through agent tools (CLI, REST, MCP). Local SQLite.",
|
|
6
6
|
"keywords": [
|
|
@@ -86,33 +86,33 @@
|
|
|
86
86
|
"tsup": "^8.5.1",
|
|
87
87
|
"tsx": "^4.19.0",
|
|
88
88
|
"@ainyc/canonry-web": "0.0.0",
|
|
89
|
-
"@ainyc/canonry-api-client": "0.0.0",
|
|
90
89
|
"@ainyc/canonry-config": "0.0.0",
|
|
91
|
-
"@ainyc/canonry-api-routes": "0.0.0",
|
|
92
90
|
"@ainyc/canonry-contracts": "0.0.0",
|
|
91
|
+
"@ainyc/canonry-api-routes": "0.0.0",
|
|
92
|
+
"@ainyc/canonry-api-client": "0.0.0",
|
|
93
93
|
"@ainyc/canonry-db": "0.0.0",
|
|
94
94
|
"@ainyc/canonry-integration-bing": "0.0.0",
|
|
95
95
|
"@ainyc/canonry-integration-cloud-run": "0.0.0",
|
|
96
|
-
"@ainyc/canonry-integration-cloudflare-queue": "0.0.0",
|
|
97
96
|
"@ainyc/canonry-integration-cloudflare-worker": "0.0.0",
|
|
98
97
|
"@ainyc/canonry-integration-commoncrawl": "0.0.0",
|
|
98
|
+
"@ainyc/canonry-integration-google": "0.0.0",
|
|
99
99
|
"@ainyc/canonry-integration-google-ads": "0.0.0",
|
|
100
|
+
"@ainyc/canonry-integration-cloudflare-queue": "0.0.0",
|
|
100
101
|
"@ainyc/canonry-integration-google-business-profile": "0.0.0",
|
|
101
|
-
"@ainyc/canonry-integration-google": "0.0.0",
|
|
102
|
-
"@ainyc/canonry-integration-google-tag-manager": "0.0.0",
|
|
103
102
|
"@ainyc/canonry-integration-google-places": "0.0.0",
|
|
103
|
+
"@ainyc/canonry-integration-google-tag-manager": "0.0.0",
|
|
104
104
|
"@ainyc/canonry-integration-openai-ads": "0.0.0",
|
|
105
|
-
"@ainyc/canonry-integration-traffic": "0.0.0",
|
|
106
|
-
"@ainyc/canonry-provider-claude": "0.0.0",
|
|
107
105
|
"@ainyc/canonry-integration-wordpress": "0.0.0",
|
|
106
|
+
"@ainyc/canonry-intelligence": "0.0.0",
|
|
107
|
+
"@ainyc/canonry-integration-traffic": "0.0.0",
|
|
108
108
|
"@ainyc/canonry-provider-cdp": "0.0.0",
|
|
109
|
+
"@ainyc/canonry-provider-claude": "0.0.0",
|
|
109
110
|
"@ainyc/canonry-provider-gemini": "0.0.0",
|
|
110
|
-
"@ainyc/canonry-provider-muse": "0.0.0",
|
|
111
|
-
"@ainyc/canonry-intelligence": "0.0.0",
|
|
112
111
|
"@ainyc/canonry-provider-local": "0.0.0",
|
|
112
|
+
"@ainyc/canonry-provider-muse": "0.0.0",
|
|
113
113
|
"@ainyc/canonry-provider-openai": "0.0.0",
|
|
114
|
-
"@ainyc/canonry-
|
|
115
|
-
"@ainyc/canonry-
|
|
114
|
+
"@ainyc/canonry-provider-perplexity": "0.0.0",
|
|
115
|
+
"@ainyc/canonry-integration-typesafe": "0.0.0"
|
|
116
116
|
},
|
|
117
117
|
"scripts": {
|
|
118
118
|
"build": "pnpm run build:cli && pnpm run build:web",
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{D as we,k as Pe,l as Ce,r as b,u as L,C as Ee,j as e,L as I}from"./vendor-tanstack-ZXXkndVj.js";import{cE as Le,d0 as Me,cx as Se,cv as Ae,L as Re,cQ as Te,cL as z,e8 as ke,e9 as qe,x as M,ea as Ie,B as g,I as P,T as w,aK as ae,aL as ne,d6 as D,eb as Ue,ec as Be,ed as _e,j as $e,s as Oe,f as ce}from"./index-DvWWyhGp.js";import{m as Ve,a as he,U as Qe,M as Ke,A as Fe,u as me}from"./v2-overview-adapter-BIOvZAlo.js";import{j as ze,o as De}from"./ChartPrimitives-CYlrwLJs.js";import{Z as He}from"./vendor-lucide-N6vOpZmh.js";import"./vendor-radix-twS1M3FF.js";import"./vendor-recharts-D-cUuLZo.js";import"./vendor-markdown-B4giJcws.js";import"./vendor-yaml-GWJz5H2G.js";const re=50,u={branded:{headline:"When they know your name",technical:"Branded queries"},"non-brand":{headline:"When they don't",technical:"Non-brand queries"}},We={plan_v1:"Setup update required",no_completed_run:"No completed measurement yet",no_population:"No queries of this type are assigned",evidence_incomplete:"Source evidence is incomplete",identity_ambiguous:Qe,not_applicable:"Not applicable for this Property"},ie={complete:{label:"Measured",tone:"positive"},partial:{label:"Partly measured",tone:"caution"},running:{label:"Measuring now",tone:"neutral"},queued:{label:"Measurement queued",tone:"neutral"},failed:{label:"Measurement failed",tone:"negative"},not_measured:{label:"Not measured",tone:"neutral"}},oe={assigned:{label:"Matches this Property",tone:"positive"},sibling:{label:"Matches another Property",tone:"caution"},ownedUnmapped:{label:"Site URL not in a Property",tone:"caution"},external:{label:"External URL",tone:"neutral"},ambiguous:{label:"Matches multiple Properties",tone:"caution"},invalid:{label:"Invalid URL",tone:"negative"}};function Ge(s){return[...s].sort((t,a)=>+(a.classification==="assigned")-+(t.classification==="assigned"))}function Ye(s){return`${s.expectedSlotId}:${s.usageEdgeId}`}function Ze({row:s}){return s.mentioned===null?e.jsxs("span",{className:"inline-flex flex-col items-start gap-0.5",children:[e.jsx(w,{tone:"neutral",children:"Not measured"}),e.jsx("span",{className:"text-xs text-muted",children:"No mention signal for this Property"})]}):e.jsx(w,{tone:s.mentioned?"positive":"neutral",children:s.mentioned?"Mentioned":"Not mentioned"})}const Je="—";function Xe({row:s}){return s.cited===null?e.jsxs("span",{className:"inline-flex flex-col items-start gap-0.5",children:[e.jsx(w,{tone:"neutral",children:"Not measured"}),e.jsx("span",{className:"text-xs text-muted",children:"Sources were not fully captured"})]}):e.jsx(w,{tone:s.cited?"positive":"neutral",children:s.cited?"Cited":"Not cited"})}function es({row:s}){return s.cited===null&&s.sources.length===0?e.jsx("p",{className:"py-2 text-sm text-secondary",children:"The sources for this answer were not fully captured, so none can be shown."}):s.sources.length===0?e.jsx("p",{className:"py-2 text-sm text-secondary",children:"This answer returned no source URLs at all."}):e.jsxs("details",{className:"mt-2","data-answer-sources":!0,children:[e.jsxs("summary",{className:"min-h-11 cursor-pointer py-3 text-sm text-secondary focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-mono-400",children:[he," (",s.sources.length,")"]}),e.jsx("div",{className:"overflow-x-auto",children:e.jsxs("table",{className:"evidence-table min-w-[420px]",children:[e.jsxs("caption",{className:"sr-only",children:["Source URLs for ",s.queryText]}),e.jsx("thead",{children:e.jsxs("tr",{children:[e.jsx("th",{children:"Match"}),e.jsx("th",{children:"URL"})]})}),e.jsx("tbody",{children:Ge(s.sources).map(t=>e.jsxs("tr",{children:[e.jsx("td",{children:e.jsx(w,{tone:oe[t.classification].tone,children:oe[t.classification].label})}),e.jsx("td",{children:e.jsx($e,{url:t.sourceUrl})})]},t.sourceUrl))})]})})]})}function ss({project:s,targetKey:t,row:a}){const r=L({..._e({client:M,path:{name:s},query:{targetKey:t,resultId:a.observationId}})});if(r.isPending)return e.jsx("p",{className:"py-2 text-sm text-secondary",role:"status","aria-live":"polite",children:"Loading the answer…"});if(r.isError)return e.jsx("p",{className:"py-2 text-sm text-secondary",role:"alert",children:"Could not load this answer."});const i=r.data?.answer;return i==null||i.trim()===""?e.jsx("p",{className:"py-2 text-sm text-secondary",children:"This answer was measured, but its text was not stored."}):e.jsx("div",{className:"py-2",children:e.jsx(Fe,{headingLevel:4,copyable:!0,children:i})})}function B(s){return We[s.reason]??"Not measured"}function U({metric:s,emphasis:t=!1}){if(s.state==="unavailable")return e.jsxs("span",{className:"inline-flex flex-col gap-0.5",children:[e.jsx("span",{className:t?"text-lg font-semibold text-secondary":"text-sm font-medium text-secondary",children:"Not measured"}),e.jsx("span",{className:"text-sm text-secondary",children:B(s)})]});const a=ce(s.value),r=s.numerator===void 0||s.denominator===void 0?null:`${s.numerator} of ${s.denominator}`,i=me(s);return e.jsxs("span",{className:"inline-flex flex-col gap-0.5 tabular-nums",children:[e.jsx("span",{className:t?"text-lg font-semibold text-heading":"text-sm font-medium text-primary",children:a}),r?e.jsx("span",{className:"text-xs text-muted",children:r}):null,i?e.jsx("span",{className:"text-xs text-muted",children:i}):null]})}function le(s,t,a){return Ue({client:M,path:{name:s},query:{scope:"property",targetKey:t,queryClass:a}})}function de(s){return s?.properties.items.at(0)}function ts({measuredAt:s,unmeasuredReason:t,queryClass:a}){const r=s===void 0?null:s===null?"No completed sweep yet":`Measured ${ze(De(s))}`;return r===null&&t===void 0?null:e.jsxs("p",{className:"supporting-copy",children:[[r,t].filter(Boolean).join(" · "),r!==null&&t===void 0?` · ${u[a].technical.toLocaleLowerCase()} only`:""]})}function as({project:s,groups:t}){return t.length===0?null:e.jsxs("section",{"aria-labelledby":"property-market",className:"page-section-divider",children:[e.jsxs("div",{className:"section-head section-head-inline",children:[e.jsxs("div",{children:[e.jsx("p",{className:"eyebrow eyebrow-soft",children:"Competitive comparison"}),e.jsxs("h2",{id:"property-market",className:"text-base font-semibold text-heading",children:["Measured at the market level",e.jsx(P,{text:"Competitors are attached to a market rather than to a single Property, because one building has nobody to be compared against. Share of voice and competitor pressure are reported for the market this Property sits in."})]})]}),e.jsx(g,{asChild:!0,type:"button",size:"sm",variant:"outline",children:e.jsx(I,{to:"/projects/$projectName",params:{projectName:s},search:a=>z(D(a),{measurementScope:"project"}),children:"Open measurement overview"})})]}),e.jsx("ul",{className:"flex flex-wrap gap-2",children:t.map(a=>e.jsxs("li",{className:"rounded-md border border-default px-3 py-1.5 text-sm text-strong",children:[a.label,e.jsxs("span",{className:"ml-2 text-xs text-muted",children:[a.competitors.length," ",a.competitors.length===1?"competitor":"competitors"]})]},a.stableKey))})]})}function q({label:s,metric:t,failed:a=!1}){if(t===void 0)return e.jsxs("div",{className:"aeo-hero-row",children:[e.jsx("p",{className:"aeo-hero-row-label",children:s}),e.jsx("p",{className:"aeo-hero-row-value text-base font-semibold text-secondary",children:a?"Unavailable":"…"}),a?e.jsx("div",{}):e.jsx("div",{className:"aeo-hero-row-bar","aria-hidden":"true"}),e.jsx("p",{className:"aeo-hero-row-detail",children:a?"Could not be loaded":"Loading"})]});if(t.state==="unavailable"){const l=B(t);return e.jsxs("div",{className:"aeo-hero-row",children:[e.jsx("p",{className:"aeo-hero-row-label",children:s}),e.jsx("p",{className:"aeo-hero-row-value text-base font-semibold text-secondary",children:"Not measured"}),e.jsx("div",{}),e.jsx("p",{className:"aeo-hero-row-detail",children:l==="Not measured"?"":l})]})}const{figure:r,sign:i}=Oe(ce(t.value)),y=t.numerator===void 0||t.denominator===void 0?null:`${t.numerator} of ${t.denominator}`,o=me(t);return e.jsxs("div",{className:"aeo-hero-row",children:[e.jsx("p",{className:"aeo-hero-row-label",children:s}),e.jsxs("p",{className:"aeo-hero-row-value text-heading",children:[r,i?e.jsx("span",{className:"text-faint",children:i}):null]}),e.jsx("div",{className:"aeo-hero-row-bar","aria-hidden":"true",children:e.jsx("div",{className:"metric-card-bar-fill progress-fill-neutral",style:{width:`${t.value*100}%`}})}),e.jsxs("p",{className:"aeo-hero-row-detail tabular-nums",children:[y??"",o?e.jsx("span",{className:"block",children:o}):null]})]})}function ns({branded:s,nonBrand:t,brandedFailed:a=!1,nonBrandFailed:r=!1}){return e.jsxs("section",{"aria-labelledby":"property-coverage-hero",children:[e.jsx("h2",{id:"property-coverage-hero",className:"sr-only",children:"Coverage for this Property"}),e.jsxs("div",{className:"space-y-5",children:[e.jsxs("div",{className:"space-y-2",children:[e.jsx("p",{className:"eyebrow eyebrow-soft",children:"Non-brand · the demand to earn"}),e.jsx(q,{label:"Mentioned",metric:t?.mentionCoverage,failed:r}),e.jsx(q,{label:"Cited",metric:t?.citationCoverage,failed:r})]}),e.jsxs("div",{className:"space-y-2",children:[e.jsx("p",{className:"eyebrow eyebrow-soft",children:"Branded · already named"}),e.jsx(q,{label:"Mentioned",metric:s?.mentionCoverage,failed:a}),e.jsx(q,{label:"Cited",metric:s?.citationCoverage,failed:a})]})]})]})}function rs({branded:s,nonBrand:t,brandedError:a,nonBrandError:r,onRetry:i}){const y=[{queryClass:"branded",row:s,isError:a},{queryClass:"non-brand",row:t,isError:r}];return e.jsxs("section",{"aria-labelledby":"property-brand-contrast",children:[e.jsx("div",{className:"section-head section-head-inline",children:e.jsxs("div",{children:[e.jsx("p",{className:"eyebrow eyebrow-soft",children:"The gap"}),e.jsxs("h2",{id:"property-brand-contrast",className:"text-base font-semibold text-heading",children:["Named versus not named",e.jsx(P,{text:"Branded queries already contain your name, so an answer engine has an easy path back to you. Non-brand queries describe the need instead, and that is the demand you have to earn. Each row is measured only over the queries assigned to this Property in that class; a class with no assigned query reads Not measured rather than 0%."})]})]})}),e.jsx("div",{className:"overflow-x-auto rounded-md border border-default",children:e.jsxs("table",{className:"evidence-table min-w-[560px]",children:[e.jsx("caption",{className:"sr-only",children:"Mention and citation coverage for this Property, split by query class"}),e.jsx("thead",{children:e.jsxs("tr",{children:[e.jsx("th",{children:"Query type"}),e.jsx("th",{children:"Mentioned in the answer"}),e.jsx("th",{children:"Cited as a source"})]})}),e.jsx("tbody",{children:y.map(({queryClass:o,row:l,isError:c})=>e.jsxs("tr",{children:[e.jsxs("td",{children:[e.jsx("span",{className:"block font-medium text-heading",children:u[o].headline}),e.jsx("span",{className:"mt-0.5 block text-xs text-muted",children:u[o].technical}),l&&c?e.jsxs("span",{className:"mt-2 flex flex-wrap items-center gap-2 text-sm text-caution",children:[e.jsx("span",{role:"status",children:"Refresh failed."}),e.jsxs(g,{type:"button",size:"sm",variant:"ghost",className:"h-11 px-3 text-sm md:h-11",onClick:()=>i(o),children:["Retry ",u[o].technical.toLocaleLowerCase()]})]}):null]}),l?e.jsxs(e.Fragment,{children:[e.jsx("td",{children:e.jsx(U,{metric:l.mentionCoverage,emphasis:!0})}),e.jsx("td",{children:e.jsx(U,{metric:l.citationCoverage,emphasis:!0})})]}):c?e.jsx("td",{colSpan:2,children:e.jsxs("div",{className:"flex flex-wrap items-center gap-3 text-sm text-secondary",children:[e.jsxs("span",{role:"alert",children:["Could not load ",u[o].technical.toLocaleLowerCase(),"."]}),e.jsxs(g,{type:"button",size:"sm",variant:"outline",className:"h-11 px-4 text-sm md:h-11",onClick:()=>i(o),children:["Retry ",u[o].technical.toLocaleLowerCase()]})]})}):e.jsxs(e.Fragment,{children:[e.jsx("td",{children:e.jsx("span",{className:"text-sm text-secondary",children:"Loading…"})}),e.jsx("td",{children:e.jsx("span",{className:"text-sm text-secondary",children:"Loading…"})})]})]},o))})]})})]})}function is({row:s,queryClass:t,isError:a}){return e.jsxs("section",{"aria-labelledby":"property-providers",className:"page-section-divider",children:[e.jsx("div",{className:"section-head section-head-inline",children:e.jsx("div",{children:e.jsxs("h2",{id:"property-providers",className:"text-base font-semibold text-heading",children:["Which engines answer for this Property",e.jsx(P,{text:"Each row is measured over the queries that engine actually answered for this Property, so the rows are a split of the same population rather than parts that add up to the Property total. An engine that answered nothing for this Property is absent instead of shown at 0%."})]})})}),s===void 0&&a?e.jsxs("p",{className:"text-sm text-secondary",children:["Details for ",u[t].technical.toLocaleLowerCase()," are unavailable. Retry that query type above."]}):s===void 0?e.jsx("p",{className:"text-sm text-secondary",children:"Loading…"}):s.providers.length===0?e.jsxs("p",{className:"text-sm text-secondary",children:["No answer engine has measured ",u[t].technical.toLocaleLowerCase()," for this Property.",s.mentionCoverage.state==="unavailable"?` ${B(s.mentionCoverage)}.`:""]}):e.jsx("div",{className:"overflow-x-auto rounded-md border border-default",children:e.jsxs("table",{className:"evidence-table min-w-[520px]",children:[e.jsx("caption",{className:"sr-only",children:"Per-engine mention and citation coverage"}),e.jsx("thead",{children:e.jsxs("tr",{children:[e.jsx("th",{children:"Engine"}),e.jsx("th",{children:"Mentioned"}),e.jsx("th",{children:"Cited"})]})}),e.jsx("tbody",{children:s.providers.map(r=>e.jsxs("tr",{children:[e.jsx("td",{className:"font-medium text-heading",children:r.provider}),e.jsx("td",{children:e.jsx(U,{metric:r.mentionCoverage})}),e.jsx("td",{children:e.jsx(U,{metric:r.citationCoverage})})]},r.provider))})]})})]})}function os(s){const t=s.questions.join(" · ");return s.questionsTruncated?`${t} +${s.questionTotal-s.questions.length} more`:t}function ls({project:s,targetKey:t,queryClass:a}){const r=L({...Be({client:M,path:{name:s},query:{targetKey:t,queryClass:a}})});if(r.isPending||r.isError)return null;const i=r.data?.competitors??[],y=r.data?.basis;return e.jsxs("section",{"aria-labelledby":"property-named-instead",className:"page-section-divider",children:[e.jsxs("div",{className:"section-head section-head-inline",children:[e.jsx("div",{children:e.jsxs("h2",{id:"property-named-instead",className:"text-base font-semibold text-heading",children:["Named instead of this Property",e.jsx(P,{text:"Counted from the answers that did not name this Property, so a name here is one an engine recommended in its place. Occurrences count answers, not positions: an engine naming the same rival in two answers counts twice, and one naming it twice in a single answer counts once."})]})}),i.length>0?e.jsxs("p",{className:"supporting-copy",children:[r.data?.total??i.length," named"]}):null]}),i.length===0?e.jsx("p",{className:"text-sm text-secondary",children:"No rival was named in the answers this Property missed. Nothing to compete with here yet."}):e.jsxs(e.Fragment,{children:[e.jsx("div",{className:"overflow-x-auto rounded-md border border-default",children:e.jsxs("table",{className:"evidence-table min-w-[420px]",children:[e.jsx("caption",{className:"sr-only",children:"Names the engines gave instead of this Property"}),e.jsx("thead",{children:e.jsxs("tr",{children:[e.jsx("th",{children:"Named"}),e.jsx("th",{children:"Answers"}),e.jsx("th",{children:"Engines"}),e.jsx("th",{children:"Queries"})]})}),e.jsx("tbody",{children:i.map(o=>e.jsxs("tr",{children:[e.jsx("td",{className:"text-strong",children:o.name}),e.jsx("td",{className:"tabular-nums text-secondary",children:o.occurrences}),e.jsxs("td",{className:"text-secondary",children:[o.providers.join(", "),o.providersTruncated?` +${o.providerTotal-o.providers.length}`:""]}),e.jsx("td",{className:"text-right",children:e.jsxs("span",{className:"inline-flex items-center justify-end gap-1",children:[e.jsx("span",{className:"tabular-nums text-secondary",children:o.questionTotal}),e.jsx(P,{text:os(o)})]})})]},o.name))})]})}),y?.state==="available"?e.jsxs("p",{className:"supporting-copy mt-2",children:[y.targetMissResults," of ",y.answeredResults," answers to ",u[a].technical.toLocaleLowerCase()," did not name this Property."]}):null]})]})}function ds({questions:s,queryClass:t}){return e.jsxs("section",{"aria-labelledby":"property-questions",className:"page-section-divider",children:[e.jsxs("div",{className:"section-head section-head-inline",children:[e.jsx("div",{children:e.jsxs("h2",{id:"property-questions",className:"text-base font-semibold text-heading",children:[u[t].technical," assigned to this Property"]})}),e.jsxs("p",{className:"supporting-copy",children:[s.length," assigned"]})]}),s.length===0?e.jsxs("p",{className:"text-sm text-secondary",children:["No ",u[t].technical.toLocaleLowerCase()," are assigned. Add one in advanced measurement setup to measure this class."]}):e.jsx("div",{className:"overflow-x-auto rounded-md border border-default",children:e.jsxs("table",{className:"evidence-table min-w-[420px]",children:[e.jsx("caption",{className:"sr-only",children:"Queries assigned to this Property"}),e.jsx("thead",{children:e.jsx("tr",{children:e.jsx("th",{children:"Query"})})}),e.jsx("tbody",{children:s.map(a=>e.jsx("tr",{children:e.jsx("td",{className:"text-secondary",children:a})},a))})]})})]})}function cs({urls:s}){return e.jsxs("section",{"aria-labelledby":"property-urls",className:"page-section-divider",children:[e.jsxs("div",{className:"section-head section-head-inline",children:[e.jsx("div",{children:e.jsxs("h2",{id:"property-urls",className:"text-base font-semibold text-heading",children:["URLs that count as this Property",e.jsx(P,{text:"A cited source URL is credited to this Property when it matches one of these. The most specific matcher wins, so a URL covered by two Properties at the same specificity is flagged for review instead of being credited to either."})]})}),e.jsxs("p",{className:"supporting-copy",children:[s.length," configured"]})]}),s.length===0?e.jsx("p",{className:"text-sm text-secondary",children:"No URLs are configured for this Property."}):e.jsx("div",{className:"overflow-x-auto rounded-md border border-default",children:e.jsxs("table",{className:"evidence-table min-w-[420px]",children:[e.jsx("caption",{className:"sr-only",children:"URL matchers configured for this Property"}),e.jsx("thead",{children:e.jsx("tr",{children:e.jsx("th",{children:"URL"})})}),e.jsx("tbody",{children:s.map(t=>e.jsx("tr",{children:e.jsx("td",{className:"break-all text-secondary",children:t})},t))})]})})]})}function hs(s,t){const a=[s.marketKey?t??"the selected market":null,s.provider?`the ${s.provider} answer engine`:null,s.model?`the ${s.model} model`:null,s.location?`location ${s.location}`:null,s.from||s.to?"a date range":null,s.measurementRunId?"a saved sweep":null].filter(r=>r!==null);return a.length===0?null:`AI Visibility is filtered to ${a.join(", ")}. This page shows the latest measurement for ${Ke.allMarkets.toLocaleLowerCase()} and answer engines.`}function Ns(){const{projectName:s,targetKey:t}=we({strict:!1}),a=Pe(),r=Ce({strict:!1}),i=b.useMemo(()=>Le(r),[r]),[y,o]=b.useState(new Set),l=s??"",c=t??"",H=!!l&&!!c,W=b.useMemo(()=>Me("portfolio",Se(Ae())),[]),S=H&&W,{canWrite:_}=Re(),C=L({...Te({client:M,path:{name:l}}),enabled:S}),G=C.data?.active?.plan,$=G?.schemaVersion===2?G:null,O=i.queryClass==="branded"||i.queryClass==="non-brand"?i.queryClass:null,Y=n=>$?.assignments.some(d=>d.targetKey===c&&d.queryClass===n)??!1,h=O??(!Y("non-brand")&&Y("branded")?"branded":"non-brand");b.useEffect(()=>{!$||O||a({to:".",replace:!0,search:n=>z(n,{queryClass:h})})},[$,O,h,a]);const v=L({...le(l,c,"branded"),enabled:S}),f=L({...le(l,c,"non-brand"),enabled:S}),V=de(v.data),Q=de(f.data),j=h==="branded"?v.data:f.data,E=h==="branded"?V:Q,Z=(h==="branded"?v.isError:f.isError)&&E===void 0,A=j?.measurement.displayedRunId;ke(l,{view:"property",selection:{mode:"advanced",scope:"property",scopeKey:c,queryClass:h,limit:10,...A?{runId:A}:{}}});const xe=E?.mentionCoverage.state==="unavailable"?B(E.mentionCoverage):void 0,ue=j===void 0?void 0:j.measurement.completedAt??null,R={client:M,path:{name:l},query:{targetKey:c,queryClass:h,shape:qe.answers,limit:re,...A?{runId:A}:{}}},m=Ee({...Ie(R),enabled:S&&j!==void 0,initialPageParam:R,getNextPageParam:n=>n.answers?.nextCursor?{path:R.path,query:{...R.query,cursor:n.answers.nextCursor}}:void 0}),K=C.data?.active??null,p=K?.plan.schemaVersion===2?K.plan:null,pe=K!==null&&p===null,T=p?.targets.find(n=>n.stableKey===c)??null,J=hs(i,p?.reportingScopes?.find(n=>n.stableKey===i.marketKey)?.label),je=b.useMemo(()=>{if(!p)return[];const n=new Map(p.querySnapshots.map(d=>[d.queryId,d.queryText]));return[...new Set(p.assignments.filter(d=>d.targetKey===c&&d.queryClass===h).flatMap(d=>{const x=n.get(d.queryId);return x===void 0?[]:[x]}))].sort((d,x)=>d.localeCompare(x))},[p,c,h]),ye=b.useMemo(()=>T?.urlMatchers.map(Ve)??[],[T]),be=b.useMemo(()=>p?.groups.filter(n=>n.targetKeys.includes(c))??[],[p,c]),N=b.useMemo(()=>(m.data?.pages??[]).flatMap(x=>x.answers?.items??[]),[m.data]),X=m.data?.pages[0]?.answers?.totalEstimate??N.length,ge=(m.data?.pages??[]).length>0&&(m.data?.pages??[]).every(n=>n.answers===void 0),ve=m.data?.pages[0]?.measurement.state,k=e.jsxs(I,{to:"/projects/$projectName",params:{projectName:l},search:D,className:"inline-flex items-center gap-1 text-xs text-muted hover:text-strong",children:[e.jsx(He,{className:"size-3.5","aria-hidden":"true"}),"Back to AI Visibility"]});if(!H)return e.jsx("div",{className:"page-container",children:e.jsx("p",{className:"text-sm text-muted",children:"Missing project name or Property key in URL."})});if(!W)return e.jsxs("div",{className:"page-container space-y-3",children:[k,e.jsx("p",{className:"text-sm text-muted",children:"This view is not available here."})]});if(C.isPending&&!C.isError)return e.jsx("div",{className:"page-container",children:e.jsxs("div",{role:"status","aria-live":"polite",children:[e.jsx("span",{className:"sr-only",children:"Loading Property"}),e.jsx("div",{className:"h-32 animate-pulse rounded-md bg-surface-subtle","aria-hidden":"true"})]})});const fe=C.isError&&C.data===void 0,ee=v.isError&&v.data===void 0,se=f.isError&&f.data===void 0;return fe||ee&&se?e.jsxs("div",{className:"page-container space-y-3",children:[k,e.jsx("p",{role:"alert",className:"text-sm text-negative",children:"Could not load this Property."}),e.jsx(g,{type:"button",size:"sm",variant:"outline",className:"h-11 px-4 text-sm md:h-11",onClick:()=>{C.refetch(),v.refetch(),f.refetch()},children:"Try again"})]}):!p||!T?e.jsxs("div",{className:"page-container space-y-3",children:[k,e.jsx("p",{role:"status",className:"text-sm text-secondary",children:p?"This Property is not in the published setup. It may have been renamed or removed.":"A Property page needs a published advanced measurement setup. Republish setup from the project Portfolio tab."}),e.jsx(g,{asChild:!0,type:"button",variant:"outline",className:"h-11 px-4 text-sm md:h-11",children:e.jsx(I,{to:"/projects/$projectName/portfolio",params:{projectName:l},children:_?pe?"Republish setup":"Open measurement setup":"View measurement setup"})})]}):e.jsxs("div",{className:"page-container space-y-8",children:[e.jsxs("div",{className:"page-header",children:[e.jsxs("div",{className:"page-header-left",children:[k,e.jsx("h1",{className:"page-title mt-2",children:T.label}),e.jsxs("p",{className:"page-subtitle",children:["Property in ",l,J?e.jsxs(e.Fragment,{children:[" · Filters not applied ",e.jsx(P,{text:J})]}):null]})]}),e.jsxs("div",{className:"page-header-right",children:[j?e.jsx(w,{tone:ie[j.measurement.state].tone,children:ie[j.measurement.state].label}):null,E&&E.flags>0?e.jsxs(w,{tone:"caution",children:[E.flags," flagged"]}):null]})]}),e.jsx(ns,{branded:V,nonBrand:Q,brandedFailed:ee,nonBrandFailed:se}),e.jsx(rs,{branded:V,nonBrand:Q,brandedError:v.isError,nonBrandError:f.isError,onRetry:n=>{n==="branded"?v.refetch():f.refetch()}}),j&&(j.measurement.state==="not_measured"||j.nextAction.kind==="run_measurement")?e.jsxs("section",{className:"flex flex-wrap items-center justify-between gap-3 border-y border-default py-4","aria-label":"Measurement next step",children:[e.jsx("p",{className:"text-sm text-secondary",children:ne()?ae:_?"Run a measurement from the project overview to collect this Property’s coverage and source evidence.":"This Property needs a new measurement before coverage and source evidence are available."}),e.jsx(g,{asChild:!0,type:"button",className:"h-11 px-4 text-sm md:h-11",children:e.jsx(I,{to:"/projects/$projectName",params:{projectName:l},search:D,children:_?"Go to AI Visibility":"View AI Visibility"})})]}):null,e.jsxs("div",{className:"flex flex-wrap items-end gap-4 border-y border-default py-4",children:[e.jsxs("div",{className:"space-y-1",children:[e.jsx("label",{htmlFor:"property-query-class",className:"block text-sm font-medium text-heading",children:"Query type"}),e.jsxs("select",{id:"property-query-class",value:h,onChange:n=>{const d=n.target.value==="branded"?"branded":"non-brand";a({to:".",search:x=>z(x,{queryClass:d})})},className:"h-11 rounded-md border border-default bg-surface px-3 text-sm text-primary focus:outline-none focus:ring-2 focus:ring-mono-400",children:[e.jsx("option",{value:"non-brand",children:u["non-brand"].technical}),e.jsx("option",{value:"branded",children:u.branded.technical})]})]}),e.jsx(ts,{measuredAt:ue,unmeasuredReason:xe,queryClass:h})]}),e.jsx(is,{row:E,queryClass:h,isError:Z}),e.jsx(ls,{project:l,targetKey:c,queryClass:h}),e.jsx(ds,{questions:je,queryClass:h}),e.jsx(cs,{urls:ye}),e.jsx(as,{project:l,groups:be}),e.jsxs("section",{"aria-labelledby":"property-evidence",className:"page-section-divider",children:[e.jsxs("div",{className:"section-head section-head-inline",children:[e.jsx("div",{children:e.jsxs("h2",{id:"property-evidence",className:"text-base font-semibold text-heading",children:["Answers the engines gave",e.jsx(P,{text:"One row per answer an engine gave for the queries assigned to this Property in the displayed measurement. Mentioned and cited are independent: an answer can name this Property without linking it, or link it without naming it. Answers that did neither are listed first, because those are what a gap is made of. Where the answer text was not stored the mention reads Not measured, never a zero. Open a row to read what the engine actually said, followed by the source URLs it returned, this Property's own first. The answer is where a miss becomes actionable: a query this Property was not named in may still have named a sibling building."})]})}),N.length>0?e.jsxs("p",{className:"supporting-copy",children:[N.length," of ",X]}):null]}),Z?e.jsxs("p",{className:"text-sm text-secondary",children:["Evidence for ",u[h].technical.toLocaleLowerCase()," is unavailable. Retry that query type above."]}):m.isPending&&N.length===0?e.jsx("p",{className:"text-sm text-secondary",children:"Loading evidence…"}):m.isError&&N.length===0?e.jsxs("div",{className:"flex flex-wrap items-center gap-3 text-sm text-secondary",children:[e.jsx("span",{role:"alert",children:"Evidence could not be loaded."}),e.jsx(g,{type:"button",size:"sm",variant:"outline",className:"h-11 px-4 text-sm md:h-11",onClick:()=>{m.refetch()},children:"Retry evidence"})]}):ve==="not_measured"?e.jsx("p",{className:"text-sm text-secondary",children:ne()?ae:"Not measured yet. Run a measurement to collect the answers for this Property."}):ge?e.jsx("p",{role:"alert",className:"text-sm text-caution",children:"This measurement was returned in an older format, so the answers cannot be shown here. The numbers above are unaffected."}):N.length===0?e.jsx("p",{className:"text-sm text-secondary",children:"No answers matched this Property in the displayed measurement."}):e.jsxs(e.Fragment,{children:[e.jsx("div",{className:"property-answer-table-container overflow-x-auto rounded-md border border-default",children:e.jsxs("table",{className:"evidence-table property-evidence-table",children:[e.jsx("caption",{className:"sr-only",children:"Answers measured for this Property"}),e.jsx("thead",{children:e.jsxs("tr",{children:[e.jsx("th",{children:"Query"}),e.jsx("th",{children:"Mentioned in the answer"}),e.jsx("th",{children:"Cited as a source"}),e.jsx("th",{children:"Sources"}),e.jsx("th",{children:e.jsx("span",{className:"sr-only",children:"Sources detail"})})]})}),e.jsx("tbody",{children:N.map(n=>{const d=Ye(n),x=y.has(d),te=`property-answer-${encodeURIComponent(d)}`;return e.jsxs(b.Fragment,{children:[e.jsxs("tr",{className:"property-answer-summary",children:[e.jsxs("td",{className:"text-secondary",children:[e.jsx("h3",{className:"text-sm font-medium text-heading",children:n.queryText}),e.jsx("span",{className:"mt-1 block text-xs text-muted",children:[n.provider,n.location].filter(Boolean).join(" · ")}),n.historical||n.bridged?e.jsx("span",{className:"mt-1 flex",children:e.jsx(w,{tone:"caution",children:"Historical"})}):null]}),e.jsxs("td",{children:[e.jsx("span",{className:"property-evidence-mobile-label","aria-hidden":"true",children:"Mentioned"}),e.jsx(Ze,{row:n})]}),e.jsxs("td",{children:[e.jsx("span",{className:"property-evidence-mobile-label","aria-hidden":"true",children:"Cited"}),e.jsx(Xe,{row:n})]}),e.jsxs("td",{className:"tabular-nums text-secondary",children:[e.jsx("span",{className:"property-evidence-mobile-label","aria-hidden":"true",children:he}),n.cited===null?Je:n.sources.length]}),e.jsx("td",{className:"text-right",children:e.jsx(g,{type:"button",size:"sm",variant:"ghost",className:"h-auto min-h-11 max-w-full whitespace-normal py-2 text-left md:h-auto","aria-expanded":x,"aria-label":x?`Hide the answer for ${n.queryText}`:`Read the answer for ${n.queryText}`,"aria-controls":x?te:void 0,onClick:()=>o(Ne=>{const F=new Set(Ne);return F.delete(d)||F.add(d),F}),children:x?"Hide answer":"Read answer"})})]}),x?e.jsx("tr",{className:"property-answer-detail",children:e.jsxs("td",{id:te,colSpan:5,className:"bg-surface-subtle px-4",children:[e.jsx(ss,{project:l,targetKey:c,row:n}),e.jsx(es,{row:n})]})}):null]},d)})})]})}),m.hasNextPage?e.jsxs("div",{className:"mt-2 flex flex-wrap items-center gap-3 text-sm text-secondary",children:[e.jsxs("span",{children:["Showing ",N.length," of ",X]}),m.isFetchNextPageError?e.jsx("span",{role:"alert",children:"Could not load more evidence."}):null,e.jsx(g,{size:"sm",variant:"outline",className:"h-11 px-4 text-sm md:h-11",disabled:m.isFetchingNextPage,onClick:()=>{m.fetchNextPage()},children:m.isFetchingNextPage?"Loading…":m.isFetchNextPageError?"Retry more evidence":`Show ${re} more`})]}):null]})]})]})}export{oe as EVIDENCE_LABELS,Ns as MeasurementPropertyPage};
|