@canonry/canonry 4.148.12 → 4.150.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-B382FYpJ.js → AuditHistoryPanel-CXjIBlWZ.js} +1 -1
- package/assets/assets/{BacklinksPage-uO5NWBJo.js → BacklinksPage-oVeQiyZ9.js} +1 -1
- package/assets/assets/ChartPrimitives-DXVLCdBi.js +1 -0
- package/assets/assets/{HistoryPage-DDxC66Rh.js → HistoryPage-B6mWz25S.js} +1 -1
- package/assets/assets/MeasurementPropertyPage-Wa-JWWlY.js +1 -0
- package/assets/assets/ProjectPage-s2Sp2gWd.js +12 -0
- package/assets/assets/{RunRow-BI6h4uOF.js → RunRow-ag3MckGi.js} +1 -1
- package/assets/assets/{RunsPage-uKBpgmHl.js → RunsPage-CQhfk-U6.js} +1 -1
- package/assets/assets/{SettingsPage-BhLkW7Pm.js → SettingsPage-C4LOqjjm.js} +1 -1
- package/assets/assets/{TrafficPage-BxElvCdW.js → TrafficPage-BrQ6ByXb.js} +1 -1
- package/assets/assets/TrafficSourceDetailPage-CAiCsj3u.js +1 -0
- package/assets/assets/{arrow-left-DF8Fd34I.js → arrow-left-CPOYDEc0.js} +1 -1
- package/assets/assets/{extract-error-message-Dzq_DLpk.js → extract-error-message-gHKEV_z-.js} +1 -1
- package/assets/assets/index-CC5bfdzz.css +1 -0
- package/assets/assets/{index-D2xFeORc.js → index-XkpXQYKF.js} +81 -81
- package/assets/assets/refresh-cw-BEX_iTPE.js +1 -0
- package/assets/assets/{trash-2-BEYteUBN.js → trash-2-NEiQsVBH.js} +1 -1
- package/assets/index.html +2 -2
- package/dist/{chunk-R6UQYXLG.js → chunk-BUAVO37B.js} +23 -1
- package/dist/{chunk-U2ETSHDL.js → chunk-CETLBKTX.js} +79 -58
- package/dist/{chunk-HWK2JSV3.js → chunk-GJOACSPY.js} +52 -9
- package/dist/{chunk-B4JACCYB.js → chunk-TS3AHKZG.js} +2 -2
- package/dist/cli.js +4 -4
- package/dist/index.js +4 -4
- package/dist/{intelligence-service-M6QKJWT7.js → intelligence-service-CEEBCERV.js} +2 -2
- package/dist/mcp.js +2 -2
- package/package.json +6 -6
- package/assets/assets/ChartPrimitives-Ca6KRJrN.js +0 -1
- package/assets/assets/MeasurementPropertyPage-oWfYibAk.js +0 -1
- package/assets/assets/ProjectPage-D9xsYkED.js +0 -12
- package/assets/assets/TrafficSourceDetailPage-Fh4-7TUe.js +0 -1
- package/assets/assets/index-D5NO3NEG.css +0 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{c as e}from"./index-XkpXQYKF.js";const o=[["path",{d:"m15 18-6-6 6-6",key:"1wnfg3"}]],a=e("chevron-left",o);const t=[["path",{d:"M3 12a9 9 0 0 1 9-9 9.75 9.75 0 0 1 6.74 2.74L21 8",key:"v9h5vc"}],["path",{d:"M21 3v5h-5",key:"1q7to0"}],["path",{d:"M21 12a9 9 0 0 1-9 9 9.75 9.75 0 0 1-6.74-2.74L3 16",key:"3uifl3"}],["path",{d:"M8 16H3v5",key:"1cv678"}]],h=e("refresh-cw",t);export{a as C,h as R};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{c as a}from"./index-
|
|
1
|
+
import{c as a}from"./index-XkpXQYKF.js";const t=[["circle",{cx:"12",cy:"12",r:"10",key:"1mglay"}],["path",{d:"M9.09 9a3 3 0 0 1 5.83 1c0 2-3 3-3 3",key:"1u773s"}],["path",{d:"M12 17h.01",key:"p32p05"}]],h=a("circle-question-mark",t);const e=[["path",{d:"M12 15V3",key:"m9g1x1"}],["path",{d:"M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4",key:"ih7n3h"}],["path",{d:"m7 10 5 5 5-5",key:"brsn70"}]],d=a("download",e);const o=[["path",{d:"M15 3h6v6",key:"1q9fwt"}],["path",{d:"M10 14 21 3",key:"gplh6r"}],["path",{d:"M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6",key:"a6xqqp"}]],p=a("external-link",o);const c=[["path",{d:"M10 11v6",key:"nco0om"}],["path",{d:"M14 11v6",key:"outv1u"}],["path",{d:"M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6",key:"miytrc"}],["path",{d:"M3 6h18",key:"d0wm0j"}],["path",{d:"M8 6V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2",key:"e791ji"}]],s=a("trash-2",c);export{h as C,d as D,p as E,s as T};
|
package/assets/index.html
CHANGED
|
@@ -12,12 +12,12 @@
|
|
|
12
12
|
<link rel="icon" type="image/png" sizes="32x32" href="./favicon-32.png" />
|
|
13
13
|
<link rel="apple-touch-icon" href="./apple-touch-icon.png" />
|
|
14
14
|
<title>Canonry</title>
|
|
15
|
-
<script type="module" crossorigin src="./assets/index-
|
|
15
|
+
<script type="module" crossorigin src="./assets/index-XkpXQYKF.js"></script>
|
|
16
16
|
<link rel="modulepreload" crossorigin href="./assets/vendor-tanstack-BjS7iY3g.js">
|
|
17
17
|
<link rel="modulepreload" crossorigin href="./assets/vendor-radix-DnzzbllM.js">
|
|
18
18
|
<link rel="modulepreload" crossorigin href="./assets/vendor-recharts-33ACLxsD.js">
|
|
19
19
|
<link rel="modulepreload" crossorigin href="./assets/vendor-markdown-CpDJch4G.js">
|
|
20
|
-
<link rel="stylesheet" crossorigin href="./assets/index-
|
|
20
|
+
<link rel="stylesheet" crossorigin href="./assets/index-CC5bfdzz.css">
|
|
21
21
|
</head>
|
|
22
22
|
<body>
|
|
23
23
|
<div id="root"></div>
|
|
@@ -5995,6 +5995,14 @@ var measurementPortfolioWeakestPropertySchema = measurementDemoPropertySchema.ex
|
|
|
5995
5995
|
ctx.addIssue({ code: z13.ZodIssueCode.custom, path: ["recommendedInsteadTruncated"], message: "Truncation must agree with the replacement total" });
|
|
5996
5996
|
}
|
|
5997
5997
|
});
|
|
5998
|
+
var measurementPortfolioMarketSchema = z13.object({
|
|
5999
|
+
groupKey: measurementV2StableKeySchema,
|
|
6000
|
+
label: measurementDemoLabelSchema,
|
|
6001
|
+
propertyCount: measurementDemoCountSchema,
|
|
6002
|
+
propertiesMentioned: measurementMetricValueSchema,
|
|
6003
|
+
mentionCoverage: measurementMetricValueSchema,
|
|
6004
|
+
citationCoverage: measurementMetricValueSchema
|
|
6005
|
+
}).strict();
|
|
5998
6006
|
var measurementPortfolioSummaryResponseSchema = z13.object({
|
|
5999
6007
|
/** A null group key means no named reporting group; spot checks may still narrow the effective Property set. */
|
|
6000
6008
|
portfolio: z13.object({
|
|
@@ -6010,6 +6018,12 @@ var measurementPortfolioSummaryResponseSchema = z13.object({
|
|
|
6010
6018
|
citationCoverage: measurementMetricValueSchema
|
|
6011
6019
|
}).strict(),
|
|
6012
6020
|
weakestProperties: z13.array(measurementPortfolioWeakestPropertySchema),
|
|
6021
|
+
/**
|
|
6022
|
+
* Every named market, worst-first. Empty when the request already narrowed to
|
|
6023
|
+
* one group (a roll-up would only restate the scope) and when the plan defines
|
|
6024
|
+
* no groups. Additive field.
|
|
6025
|
+
*/
|
|
6026
|
+
markets: z13.array(measurementPortfolioMarketSchema),
|
|
6013
6027
|
totalProperties: measurementDemoCountSchema,
|
|
6014
6028
|
truncated: z13.boolean()
|
|
6015
6029
|
}).strict();
|
|
@@ -13793,6 +13807,12 @@ function isGhostTelemetryEvent(eventName, properties) {
|
|
|
13793
13807
|
return GHOST_TELEMETRY_TEST_LOCATIONS.has(location);
|
|
13794
13808
|
}
|
|
13795
13809
|
|
|
13810
|
+
// ../contracts/src/trend-stability.ts
|
|
13811
|
+
var MIN_TREND_POINTS = 4;
|
|
13812
|
+
function isTrendBaseline(points) {
|
|
13813
|
+
return points.length < MIN_TREND_POINTS;
|
|
13814
|
+
}
|
|
13815
|
+
|
|
13796
13816
|
export {
|
|
13797
13817
|
__export,
|
|
13798
13818
|
apiKeyDtoSchema,
|
|
@@ -14368,5 +14388,7 @@ export {
|
|
|
14368
14388
|
bucketOnboardingCount,
|
|
14369
14389
|
onboardingTelemetryEventSchema,
|
|
14370
14390
|
telemetryEventAcceptedDtoSchema,
|
|
14371
|
-
isGhostTelemetryEvent
|
|
14391
|
+
isGhostTelemetryEvent,
|
|
14392
|
+
MIN_TREND_POINTS,
|
|
14393
|
+
isTrendBaseline
|
|
14372
14394
|
};
|
|
@@ -10,7 +10,7 @@ import {
|
|
|
10
10
|
loadConfig,
|
|
11
11
|
loadConfigRaw,
|
|
12
12
|
saveConfigPatch
|
|
13
|
-
} from "./chunk-
|
|
13
|
+
} from "./chunk-TS3AHKZG.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-GJOACSPY.js";
|
|
130
130
|
import {
|
|
131
131
|
AGENT_MEMORY_VALUE_MAX_BYTES,
|
|
132
132
|
AGENT_PROVIDER_IDS,
|
|
@@ -218,7 +218,7 @@ import {
|
|
|
218
218
|
validationError,
|
|
219
219
|
winnabilityClassLabel,
|
|
220
220
|
withRetry
|
|
221
|
-
} from "./chunk-
|
|
221
|
+
} from "./chunk-BUAVO37B.js";
|
|
222
222
|
|
|
223
223
|
// src/telemetry.ts
|
|
224
224
|
import crypto from "crypto";
|
|
@@ -5674,6 +5674,7 @@ async function inspectUrlsPaced(urls, cb, deps = {}) {
|
|
|
5674
5674
|
const sleep3 = deps.sleep ?? defaultSleep;
|
|
5675
5675
|
const jitter = deps.jitter ?? Math.random;
|
|
5676
5676
|
const concurrency = Math.max(1, Math.min(deps.concurrency ?? INSPECT_MAX_CONCURRENCY, urls.length || 1));
|
|
5677
|
+
const isRetryable = deps.isRetryable ?? isRetryableGscInspectError;
|
|
5677
5678
|
let inspected = 0;
|
|
5678
5679
|
let errors = 0;
|
|
5679
5680
|
let consecutiveRetryableFailures = 0;
|
|
@@ -5699,7 +5700,7 @@ async function inspectUrlsPaced(urls, cb, deps = {}) {
|
|
|
5699
5700
|
maxRetries: INSPECT_MAX_RETRIES,
|
|
5700
5701
|
baseDelayMs: INSPECT_BASE_DELAY_MS,
|
|
5701
5702
|
maxDelayMs: INSPECT_MAX_BACKOFF_MS,
|
|
5702
|
-
isRetryable
|
|
5703
|
+
isRetryable,
|
|
5703
5704
|
sleep: sleep3,
|
|
5704
5705
|
onRetry: ({ attempt, delayMs, err }) => deps.log?.info("inspect.retry", {
|
|
5705
5706
|
url,
|
|
@@ -5714,7 +5715,7 @@ async function inspectUrlsPaced(urls, cb, deps = {}) {
|
|
|
5714
5715
|
} catch (err) {
|
|
5715
5716
|
errors++;
|
|
5716
5717
|
cb.onError(url, err, index);
|
|
5717
|
-
if (
|
|
5718
|
+
if (isRetryable(err)) {
|
|
5718
5719
|
consecutiveRetryableFailures++;
|
|
5719
5720
|
if (consecutiveRetryableFailures >= INSPECT_FAILFAST_THRESHOLD) {
|
|
5720
5721
|
deps.log?.error("inspect.circuit-break", {
|
|
@@ -5918,61 +5919,81 @@ async function executeBingInspectSitemap(db, runId, projectId, opts) {
|
|
|
5918
5919
|
});
|
|
5919
5920
|
blockedUrls = /* @__PURE__ */ new Set();
|
|
5920
5921
|
}
|
|
5922
|
+
const skipped = Math.max(0, sitemapUrls.length - INSPECT_SWEEP_MAX_URLS);
|
|
5923
|
+
const targetUrls = skipped > 0 ? sitemapUrls.slice(0, INSPECT_SWEEP_MAX_URLS) : sitemapUrls;
|
|
5924
|
+
if (skipped > 0) {
|
|
5925
|
+
log7.warn("sitemap.over-budget", {
|
|
5926
|
+
runId,
|
|
5927
|
+
projectId,
|
|
5928
|
+
sitemapUrls: sitemapUrls.length,
|
|
5929
|
+
inspecting: targetUrls.length,
|
|
5930
|
+
skipped,
|
|
5931
|
+
dailyQuota: INSPECT_DAILY_QUOTA,
|
|
5932
|
+
note: `Sitemap has ${sitemapUrls.length} pages; inspecting the first ${targetUrls.length}. ${skipped} pages will not have a verdict from this run.`
|
|
5933
|
+
});
|
|
5934
|
+
}
|
|
5935
|
+
const siteUrl = conn.siteUrl;
|
|
5921
5936
|
let inspected = 0;
|
|
5922
5937
|
let errors = 0;
|
|
5923
|
-
|
|
5924
|
-
|
|
5925
|
-
|
|
5926
|
-
|
|
5927
|
-
|
|
5928
|
-
|
|
5929
|
-
|
|
5930
|
-
|
|
5931
|
-
|
|
5932
|
-
|
|
5933
|
-
derivedInIndex =
|
|
5934
|
-
|
|
5935
|
-
|
|
5936
|
-
|
|
5937
|
-
|
|
5938
|
-
|
|
5939
|
-
|
|
5940
|
-
|
|
5938
|
+
const outcome = await inspectUrlsPaced(
|
|
5939
|
+
targetUrls,
|
|
5940
|
+
{
|
|
5941
|
+
inspectOne: (pageUrl) => getUrlInfo(conn.apiKey, siteUrl, pageUrl),
|
|
5942
|
+
onResult: (pageUrl, result) => {
|
|
5943
|
+
const inspectedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
5944
|
+
const httpCode = result.HttpStatus ?? result.HttpCode ?? null;
|
|
5945
|
+
const lastCrawledDate = parseBingDate(result.LastCrawledDate);
|
|
5946
|
+
const inIndexDate = parseBingDate(result.InIndexDate);
|
|
5947
|
+
const discoveryDate = parseBingDate(result.DiscoveryDate);
|
|
5948
|
+
let derivedInIndex = null;
|
|
5949
|
+
if (result.DocumentSize != null && result.DocumentSize > 0) {
|
|
5950
|
+
derivedInIndex = true;
|
|
5951
|
+
} else if (lastCrawledDate != null) {
|
|
5952
|
+
derivedInIndex = httpCode != null && httpCode >= 400 ? false : true;
|
|
5953
|
+
} else if (discoveryDate != null) {
|
|
5954
|
+
derivedInIndex = false;
|
|
5955
|
+
}
|
|
5956
|
+
if (derivedInIndex === true && blockedUrls.has(pageUrl)) {
|
|
5957
|
+
derivedInIndex = false;
|
|
5958
|
+
}
|
|
5959
|
+
db.insert(bingUrlInspections).values({
|
|
5960
|
+
id: crypto10.randomUUID(),
|
|
5961
|
+
projectId,
|
|
5962
|
+
url: pageUrl,
|
|
5963
|
+
httpCode,
|
|
5964
|
+
inIndex: derivedInIndex,
|
|
5965
|
+
lastCrawledDate,
|
|
5966
|
+
inIndexDate,
|
|
5967
|
+
inspectedAt,
|
|
5968
|
+
syncRunId: runId,
|
|
5969
|
+
createdAt: inspectedAt,
|
|
5970
|
+
documentSize: result.DocumentSize ?? null,
|
|
5971
|
+
anchorCount: result.AnchorCount ?? null,
|
|
5972
|
+
discoveryDate
|
|
5973
|
+
}).run();
|
|
5974
|
+
inspected++;
|
|
5975
|
+
log7.info("inspect.url-done", { runId, projectId, url: pageUrl, progress: `${inspected}/${targetUrls.length}` });
|
|
5976
|
+
},
|
|
5977
|
+
onError: (pageUrl, err) => {
|
|
5978
|
+
errors++;
|
|
5979
|
+
log7.error("inspect.url-failed", {
|
|
5980
|
+
runId,
|
|
5981
|
+
projectId,
|
|
5982
|
+
url: pageUrl,
|
|
5983
|
+
error: err instanceof Error ? err.message : String(err)
|
|
5984
|
+
});
|
|
5941
5985
|
}
|
|
5942
|
-
|
|
5943
|
-
|
|
5944
|
-
|
|
5945
|
-
|
|
5946
|
-
|
|
5947
|
-
|
|
5948
|
-
|
|
5949
|
-
|
|
5950
|
-
|
|
5951
|
-
|
|
5952
|
-
|
|
5953
|
-
documentSize: result.DocumentSize ?? null,
|
|
5954
|
-
anchorCount: result.AnchorCount ?? null,
|
|
5955
|
-
discoveryDate
|
|
5956
|
-
}).run();
|
|
5957
|
-
inspected++;
|
|
5958
|
-
log7.info("inspect.url-done", {
|
|
5959
|
-
runId,
|
|
5960
|
-
projectId,
|
|
5961
|
-
url: pageUrl,
|
|
5962
|
-
progress: `${inspected}/${sitemapUrls.length}`
|
|
5963
|
-
});
|
|
5964
|
-
} catch (err) {
|
|
5965
|
-
errors++;
|
|
5966
|
-
log7.error("inspect.url-failed", {
|
|
5967
|
-
runId,
|
|
5968
|
-
projectId,
|
|
5969
|
-
url: pageUrl,
|
|
5970
|
-
error: err instanceof Error ? err.message : String(err)
|
|
5971
|
-
});
|
|
5972
|
-
}
|
|
5973
|
-
if (inspected + errors < sitemapUrls.length) {
|
|
5974
|
-
await new Promise((r) => setTimeout(r, 1e3));
|
|
5975
|
-
}
|
|
5986
|
+
},
|
|
5987
|
+
{ isRetryable: isRetryableHttpError, concurrency: 1, log: log7, ...opts.pacedDeps }
|
|
5988
|
+
);
|
|
5989
|
+
if (outcome.aborted) {
|
|
5990
|
+
log7.error("inspect.circuit-break", {
|
|
5991
|
+
runId,
|
|
5992
|
+
projectId,
|
|
5993
|
+
inspected,
|
|
5994
|
+
errors,
|
|
5995
|
+
note: "Bing inspection stopped early after sustained failures; the remaining pages were not attempted."
|
|
5996
|
+
});
|
|
5976
5997
|
}
|
|
5977
5998
|
const allInspections = db.select().from(bingUrlInspections).where(eq8(bingUrlInspections.projectId, projectId)).orderBy(desc3(bingUrlInspections.inspectedAt)).all();
|
|
5978
5999
|
const latestByUrl = /* @__PURE__ */ new Map();
|
|
@@ -7411,7 +7432,7 @@ function readStoredGroundingSources(rawResponse) {
|
|
|
7411
7432
|
return result;
|
|
7412
7433
|
}
|
|
7413
7434
|
async function backfillInsightsCommand(project, opts) {
|
|
7414
|
-
const { IntelligenceService: IntelligenceService2 } = await import("./intelligence-service-
|
|
7435
|
+
const { IntelligenceService: IntelligenceService2 } = await import("./intelligence-service-CEEBCERV.js");
|
|
7415
7436
|
const config = loadConfig();
|
|
7416
7437
|
const db = createClient(config.database);
|
|
7417
7438
|
migrate(db);
|
|
@@ -61,6 +61,7 @@ import {
|
|
|
61
61
|
MEASUREMENT_PAGE_MAX_LIMIT,
|
|
62
62
|
MEASUREMENT_PLAN_V2_SCHEMA_VERSION,
|
|
63
63
|
MIN_DOMAIN_BRAND_KEY_LENGTH,
|
|
64
|
+
MIN_TREND_POINTS,
|
|
64
65
|
MODEL_ATTRIBUTION_EVENT_LIMIT,
|
|
65
66
|
MeasurementEvidenceShapes,
|
|
66
67
|
MeasurementPlanValidationError,
|
|
@@ -290,6 +291,7 @@ import {
|
|
|
290
291
|
isBrowserProvider,
|
|
291
292
|
isReadOnlyKey,
|
|
292
293
|
isRetryableHttpError,
|
|
294
|
+
isTrendBaseline,
|
|
293
295
|
isVertexGroundingRedirect,
|
|
294
296
|
isoDateDaysBeforeInTimeZone,
|
|
295
297
|
keywordDtoSchema,
|
|
@@ -519,7 +521,7 @@ import {
|
|
|
519
521
|
wordpressSchemaDeployResultDtoSchema,
|
|
520
522
|
wordpressSchemaStatusResultDtoSchema,
|
|
521
523
|
wordpressStatusDtoSchema
|
|
522
|
-
} from "./chunk-
|
|
524
|
+
} from "./chunk-BUAVO37B.js";
|
|
523
525
|
|
|
524
526
|
// src/intelligence-service.ts
|
|
525
527
|
import { eq as eq57, desc as desc26, asc as asc11, and as and45, ne as ne7, or as or11, inArray as inArray19, gte as gte13, lte as lte10 } from "drizzle-orm";
|
|
@@ -6326,12 +6328,6 @@ function categorizeQueryByIntent(query, brandTokens) {
|
|
|
6326
6328
|
return "other";
|
|
6327
6329
|
}
|
|
6328
6330
|
|
|
6329
|
-
// ../intelligence/src/trend-stability.ts
|
|
6330
|
-
var MIN_TREND_POINTS = 4;
|
|
6331
|
-
function isTrendBaseline(points) {
|
|
6332
|
-
return points.length < MIN_TREND_POINTS;
|
|
6333
|
-
}
|
|
6334
|
-
|
|
6335
6331
|
// ../intelligence/src/citation-scorecard.ts
|
|
6336
6332
|
function buildCitationScorecard(snapshots, queryLookup) {
|
|
6337
6333
|
if (snapshots.length === 0) {
|
|
@@ -16687,6 +16683,8 @@ function filteredOverviewWithDb(db, active, plan, run, filters, targetKeys) {
|
|
|
16687
16683
|
const usageEdges = materialized.input.usageEdges.filter((edge) => filters.queryClass === "all" || materialized.edgeQueryClass.get(edge.id) === filters.queryClass);
|
|
16688
16684
|
return {
|
|
16689
16685
|
materialized,
|
|
16686
|
+
expectedSlots,
|
|
16687
|
+
usageEdges,
|
|
16690
16688
|
overview: buildMeasurementOverview({
|
|
16691
16689
|
...materialized.input,
|
|
16692
16690
|
expectedSlots,
|
|
@@ -16812,6 +16810,39 @@ function targetKeysForRun(plan, run, requested, requireEntireScope) {
|
|
|
16812
16810
|
}
|
|
16813
16811
|
return selected;
|
|
16814
16812
|
}
|
|
16813
|
+
function marketRollup(plan, run, materialized, expectedSlots, usageEdges, scopedToOneGroup) {
|
|
16814
|
+
if (scopedToOneGroup) return [];
|
|
16815
|
+
return plan.groups.map((group) => {
|
|
16816
|
+
const targetKeys = targetKeysForRun(plan, run, group.targetKeys, false);
|
|
16817
|
+
const overview = buildMeasurementOverview({
|
|
16818
|
+
...materialized.input,
|
|
16819
|
+
expectedSlots,
|
|
16820
|
+
usageEdges,
|
|
16821
|
+
scopeTargetIds: targetKeys
|
|
16822
|
+
});
|
|
16823
|
+
return {
|
|
16824
|
+
groupKey: group.stableKey,
|
|
16825
|
+
label: group.label,
|
|
16826
|
+
propertyCount: targetKeys.length,
|
|
16827
|
+
propertiesMentioned: countMetric2(overview.propertiesMentioned),
|
|
16828
|
+
mentionCoverage: coverageMetric2(overview.mentionCoverage),
|
|
16829
|
+
citationCoverage: coverageMetric2(overview.citationCoverage)
|
|
16830
|
+
};
|
|
16831
|
+
}).sort(compareWeakestMarket);
|
|
16832
|
+
}
|
|
16833
|
+
function compareWeakestMarket(a, b) {
|
|
16834
|
+
const aUnavailable = a.mentionCoverage.state === "unavailable" || a.citationCoverage.state === "unavailable";
|
|
16835
|
+
const bUnavailable = b.mentionCoverage.state === "unavailable" || b.citationCoverage.state === "unavailable";
|
|
16836
|
+
if (aUnavailable !== bUnavailable) return aUnavailable ? 1 : -1;
|
|
16837
|
+
if (aUnavailable || bUnavailable) return compareText13(a.label, b.label) || compareText13(a.groupKey, b.groupKey);
|
|
16838
|
+
if (a.mentionCoverage.state === "available" && b.mentionCoverage.state === "available" && a.mentionCoverage.value !== b.mentionCoverage.value) {
|
|
16839
|
+
return a.mentionCoverage.value - b.mentionCoverage.value;
|
|
16840
|
+
}
|
|
16841
|
+
if (a.citationCoverage.state === "available" && b.citationCoverage.state === "available" && a.citationCoverage.value !== b.citationCoverage.value) {
|
|
16842
|
+
return a.citationCoverage.value - b.citationCoverage.value;
|
|
16843
|
+
}
|
|
16844
|
+
return compareText13(a.label, b.label) || compareText13(a.groupKey, b.groupKey);
|
|
16845
|
+
}
|
|
16815
16846
|
function portfolioResponse(db, active, plan, query) {
|
|
16816
16847
|
const group = query.groupKey === void 0 ? void 0 : requireGroup2(plan, query.groupKey);
|
|
16817
16848
|
const run = selectMeasurementQuestionRun(db, active.version.projectId, active, query.runId);
|
|
@@ -16845,11 +16876,22 @@ function portfolioResponse(db, active, plan, query) {
|
|
|
16845
16876
|
citationCoverage: unavailable3("no_completed_run")
|
|
16846
16877
|
},
|
|
16847
16878
|
weakestProperties: rows2.slice(0, limit2),
|
|
16879
|
+
// Sorted through the same comparator as the measured branch. Plan order
|
|
16880
|
+
// is `stableKey`, so emitting it raw put markets in an order the schema
|
|
16881
|
+
// documents as worst-first and that changes the moment a run lands.
|
|
16882
|
+
markets: group !== void 0 ? [] : plan.groups.map((g) => ({
|
|
16883
|
+
groupKey: g.stableKey,
|
|
16884
|
+
label: g.label,
|
|
16885
|
+
propertyCount: g.targetKeys.length,
|
|
16886
|
+
propertiesMentioned: unavailable3("no_completed_run"),
|
|
16887
|
+
mentionCoverage: unavailable3("no_completed_run"),
|
|
16888
|
+
citationCoverage: unavailable3("no_completed_run")
|
|
16889
|
+
})).sort(compareWeakestMarket),
|
|
16848
16890
|
totalProperties: rows2.length,
|
|
16849
16891
|
truncated: rows2.length > limit2
|
|
16850
16892
|
});
|
|
16851
16893
|
}
|
|
16852
|
-
const { materialized, overview } = filteredOverviewWithDb(db, active, plan, run, filters, targetKeys);
|
|
16894
|
+
const { materialized, overview, expectedSlots: filteredSlots, usageEdges: filteredEdges } = filteredOverviewWithDb(db, active, plan, run, filters, targetKeys);
|
|
16853
16895
|
const measured = new Map(overview.properties.map((row) => [row.targetId, row]));
|
|
16854
16896
|
const rows = targets.map((target) => {
|
|
16855
16897
|
const row = measured.get(target.stableKey);
|
|
@@ -16879,6 +16921,7 @@ function portfolioResponse(db, active, plan, query) {
|
|
|
16879
16921
|
citationCoverage: coverageMetric2(overview.citationCoverage)
|
|
16880
16922
|
},
|
|
16881
16923
|
weakestProperties: rows.slice(0, limit),
|
|
16924
|
+
markets: marketRollup(plan, run, materialized, filteredSlots, filteredEdges, group !== void 0),
|
|
16882
16925
|
totalProperties: rows.length,
|
|
16883
16926
|
truncated: rows.length > limit
|
|
16884
16927
|
});
|
|
@@ -27671,7 +27714,7 @@ var routeCatalog = [
|
|
|
27671
27714
|
method: "get",
|
|
27672
27715
|
path: "/api/v1/projects/{name}/measurement-portfolio-summary",
|
|
27673
27716
|
summary: "Get the weakest measured Properties",
|
|
27674
|
-
description: "Returns a compact, revision-pinned portfolio ranking from stored results. It defaults to Non-brand questions, ranks measured mention coverage before citation coverage, and keeps unavailable rows separate from measured weakness. Replacement names come only from stored answer extraction. It never starts provider work.",
|
|
27717
|
+
description: "Returns a compact, revision-pinned portfolio ranking from stored results, plus a worst-first roll-up of every named market. It defaults to Non-brand questions, ranks measured mention coverage before citation coverage, and keeps unavailable rows separate from measured weakness. Every market is scoped to the displayed run, so a market row matches that market read with groupKey; markets may share Properties and never sum to the portfolio totals. The markets array is empty when the request already narrowed to one group. Replacement names come only from stored answer extraction. It never starts provider work.",
|
|
27675
27718
|
tags: ["measurement-plans"],
|
|
27676
27719
|
parameters: [
|
|
27677
27720
|
nameParameter,
|
|
@@ -81,7 +81,7 @@ import {
|
|
|
81
81
|
trafficConnectWordpressRequestSchema,
|
|
82
82
|
trafficEventKindSchema,
|
|
83
83
|
trafficSeriesGranularitySchema
|
|
84
|
-
} from "./chunk-
|
|
84
|
+
} from "./chunk-BUAVO37B.js";
|
|
85
85
|
|
|
86
86
|
// src/config.ts
|
|
87
87
|
import fs from "fs";
|
|
@@ -9431,7 +9431,7 @@ var canonryMcpTools = [
|
|
|
9431
9431
|
defineTool({
|
|
9432
9432
|
name: "canonry_measurement_portfolio_summary",
|
|
9433
9433
|
title: "Summarize measured Properties",
|
|
9434
|
-
description: "Start here to rank the weakest measured Properties and their stored replacement names. Reads stored data only; it never starts provider work.",
|
|
9434
|
+
description: "Start here to rank the weakest measured Properties and their stored replacement names, and to compare every named market worst-first. Each market is scoped to the displayed run; markets may share Properties, so they never sum to the portfolio totals. Reads stored data only; it never starts provider work.",
|
|
9435
9435
|
access: "read",
|
|
9436
9436
|
tier: "monitoring",
|
|
9437
9437
|
inputSchema: measurementPortfolioSummaryInputSchema,
|
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-CETLBKTX.js";
|
|
34
34
|
import {
|
|
35
35
|
CliError,
|
|
36
36
|
EXIT_SYSTEM_ERROR,
|
|
@@ -50,7 +50,7 @@ import {
|
|
|
50
50
|
saveConfigPatch,
|
|
51
51
|
systemError,
|
|
52
52
|
usageError
|
|
53
|
-
} from "./chunk-
|
|
53
|
+
} from "./chunk-TS3AHKZG.js";
|
|
54
54
|
import {
|
|
55
55
|
apiKeys,
|
|
56
56
|
createClient,
|
|
@@ -58,7 +58,7 @@ import {
|
|
|
58
58
|
projects,
|
|
59
59
|
queries,
|
|
60
60
|
renderReportHtml
|
|
61
|
-
} from "./chunk-
|
|
61
|
+
} from "./chunk-GJOACSPY.js";
|
|
62
62
|
import {
|
|
63
63
|
AdsDeliverySnapshotStatuses,
|
|
64
64
|
AdsHistoricalCampaignRollupStatuses,
|
|
@@ -122,7 +122,7 @@ import {
|
|
|
122
122
|
providerQuotaPolicySchema,
|
|
123
123
|
resolveProviderInput,
|
|
124
124
|
winnabilityClassSchema
|
|
125
|
-
} from "./chunk-
|
|
125
|
+
} from "./chunk-BUAVO37B.js";
|
|
126
126
|
|
|
127
127
|
// src/cli.ts
|
|
128
128
|
import { pathToFileURL } from "url";
|
package/dist/index.js
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import {
|
|
2
2
|
createServer
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-CETLBKTX.js";
|
|
4
4
|
import {
|
|
5
5
|
loadConfig
|
|
6
|
-
} from "./chunk-
|
|
7
|
-
import "./chunk-
|
|
8
|
-
import "./chunk-
|
|
6
|
+
} from "./chunk-TS3AHKZG.js";
|
|
7
|
+
import "./chunk-GJOACSPY.js";
|
|
8
|
+
import "./chunk-BUAVO37B.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-TS3AHKZG.js";
|
|
7
7
|
import {
|
|
8
8
|
isReadOnlyKey
|
|
9
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-BUAVO37B.js";
|
|
10
10
|
|
|
11
11
|
// src/mcp/cli.ts
|
|
12
12
|
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@canonry/canonry",
|
|
3
|
-
"version": "4.
|
|
3
|
+
"version": "4.150.1",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Agent-first open-source AEO operating platform - track how answer engines cite your domain",
|
|
6
6
|
"license": "FSL-1.1-ALv2",
|
|
@@ -72,20 +72,20 @@
|
|
|
72
72
|
"@ainyc/canonry-contracts": "0.0.0",
|
|
73
73
|
"@ainyc/canonry-db": "0.0.0",
|
|
74
74
|
"@ainyc/canonry-integration-bing": "0.0.0",
|
|
75
|
-
"@ainyc/canonry-integration-openai-ads": "0.0.0",
|
|
76
75
|
"@ainyc/canonry-integration-cloud-run": "0.0.0",
|
|
76
|
+
"@ainyc/canonry-integration-commoncrawl": "0.0.0",
|
|
77
77
|
"@ainyc/canonry-integration-google": "0.0.0",
|
|
78
|
-
"@ainyc/canonry-integration-
|
|
78
|
+
"@ainyc/canonry-integration-openai-ads": "0.0.0",
|
|
79
79
|
"@ainyc/canonry-integration-google-business-profile": "0.0.0",
|
|
80
|
+
"@ainyc/canonry-integration-google-places": "0.0.0",
|
|
80
81
|
"@ainyc/canonry-integration-traffic": "0.0.0",
|
|
81
|
-
"@ainyc/canonry-integration-commoncrawl": "0.0.0",
|
|
82
82
|
"@ainyc/canonry-integration-wordpress": "0.0.0",
|
|
83
|
-
"@ainyc/canonry-provider-claude": "0.0.0",
|
|
84
83
|
"@ainyc/canonry-intelligence": "0.0.0",
|
|
85
84
|
"@ainyc/canonry-provider-cdp": "0.0.0",
|
|
85
|
+
"@ainyc/canonry-provider-claude": "0.0.0",
|
|
86
86
|
"@ainyc/canonry-provider-gemini": "0.0.0",
|
|
87
|
-
"@ainyc/canonry-provider-openai": "0.0.0",
|
|
88
87
|
"@ainyc/canonry-provider-local": "0.0.0",
|
|
88
|
+
"@ainyc/canonry-provider-openai": "0.0.0",
|
|
89
89
|
"@ainyc/canonry-provider-perplexity": "0.0.0"
|
|
90
90
|
},
|
|
91
91
|
"scripts": {
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{c as n}from"./index-D2xFeORc.js";const c=[["path",{d:"m15 18-6-6 6-6",key:"1wnfg3"}]],d=n("chevron-left",c);const i=[["path",{d:"M3 12a9 9 0 0 1 9-9 9.75 9.75 0 0 1 6.74 2.74L21 8",key:"v9h5vc"}],["path",{d:"M21 3v5h-5",key:"1q7to0"}],["path",{d:"M21 12a9 9 0 0 1-9 9 9.75 9.75 0 0 1-6.74-2.74L3 16",key:"3uifl3"}],["path",{d:"M8 16H3v5",key:"1cv678"}]],v=n("refresh-cw",i),f={contentStyle:{backgroundColor:"var(--chart-tooltip-bg, #18181b)",border:"1px solid var(--chart-tooltip-border, #3f3f46)",borderRadius:8,fontSize:12},labelStyle:{color:"var(--chart-tooltip-label, #e4e4e7)"},itemStyle:{color:"var(--chart-tooltip-item, #a1a1aa)"}},u={fill:"var(--chart-neutral-text-dim, #71717a)",fontSize:11},l="var(--chart-grid, #27272a)",b="var(--chart-axis, #27272a)",r=["var(--chart-series-1, #34d399)","var(--chart-series-2, #60a5fa)","var(--chart-series-3, #f472b6)","var(--chart-series-4, #facc15)","var(--chart-series-5, #a78bfa)","var(--chart-series-6, #fb923c)","var(--chart-series-7, #22d3ee)","var(--chart-series-8, #f87171)"],s={gemini:"#60a5fa",openai:"#34d399",claude:"#fb923c",perplexity:"#22d3ee",local:"#a78bfa"};function m(a,t=0){return s[a]??r[t%r.length]}const p={text:"var(--chart-neutral-text, #a1a1aa)",textDim:"var(--chart-neutral-text-dim, #71717a)",textFaint:"var(--chart-neutral-text-faint, #52525b)",surface:"var(--chart-neutral-surface, #27272a)",trackSubtle:"var(--chart-neutral-track-subtle, rgb(255 255 255 / 0.04))",gridLine:"var(--chart-neutral-grid-line, rgb(255 255 255 / 0.06))"},S={positive:"var(--chart-tone-positive, #34d399)",positiveDeep:"var(--chart-tone-positive-deep, #10b981)",caution:"var(--chart-tone-caution, #fbbf24)",negative:"var(--chart-tone-negative, #fb7185)"};function g(a){return a}function o(a){const t=/^(\d{4})-(\d{2})-(\d{2})/.exec(a);return t?{year:Number(t[1]),month:Number(t[2]),day:Number(t[3])}:null}function R(a){const t=String(a),e=o(t);return e?new Date(Date.UTC(e.year,e.month-1,e.day)).toLocaleDateString(void 0,{timeZone:"UTC",month:"short",day:"numeric",year:"numeric"}):t}function C(a){const t=o(String(a));return t?`${t.month}/${t.day}`:String(a)}function T(a){return new Date(a).toLocaleDateString(void 0,{month:"short",day:"numeric",year:"numeric"})}function y(a){const t=new Date(a);return`${t.getMonth()+1}/${t.getDate()}`}export{d as C,v as R,b as a,u as b,R as c,f as d,p as e,C as f,r as g,S as h,l as i,y as j,T as k,g as o,m as p};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{C as te,r as v,u as T,D as ne,j as e,L as q}from"./vendor-tanstack-BjS7iY3g.js";import{bL as ae,bS as re,d2 as ie,d3 as oe,bY as le,bM as de,B as b,T as g,I as C,d4 as ce,m as B}from"./index-D2xFeORc.js";import{m as he}from"./v2-overview-adapter-BHmxTmCf.js";import{A as xe}from"./arrow-left-DF8Fd34I.js";import"./vendor-radix-DnzzbllM.js";import"./vendor-recharts-33ACLxsD.js";import"./vendor-markdown-CpDJch4G.js";const F=50,l={branded:{headline:"When they know your name",technical:"Branded questions"},"non-brand":{headline:"When they don't",technical:"Non-brand questions"}},me={plan_v1:"Setup update required",no_completed_run:"No completed measurement yet",no_population:"No questions of this type are assigned",evidence_incomplete:"Source evidence is incomplete",not_applicable:"Not applicable for this Property"},O={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"}},V={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 pe(s){return[...s].sort((n,a)=>+(a.classification==="assigned")-+(n.classification==="assigned"))}function ue(s){return`${s.expectedSlotId}:${s.usageEdgeId}`}function je({row:s}){return s.mentioned===null?e.jsxs("span",{className:"inline-flex flex-col items-start gap-0.5",children:[e.jsx(g,{tone:"neutral",children:"Not measured"}),e.jsx("span",{className:"text-xs text-muted",children:"No mention signal for this Property"})]}):e.jsx(g,{tone:s.mentioned?"positive":"neutral",children:s.mentioned?"Mentioned":"Not mentioned"})}const ye="—";function be({row:s}){return s.cited===null?e.jsxs("span",{className:"inline-flex flex-col items-start gap-0.5",children:[e.jsx(g,{tone:"neutral",children:"Not measured"}),e.jsx("span",{className:"text-xs text-muted",children:"Sources were not fully captured"})]}):e.jsx(g,{tone:s.cited?"positive":"neutral",children:s.cited?"Cited":"Not cited"})}function ge({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.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:pe(s.sources).map(n=>e.jsxs("tr",{children:[e.jsx("td",{children:e.jsx(g,{tone:V[n.classification].tone,children:V[n.classification].label})}),e.jsx("td",{className:"break-all text-secondary",children:n.sourceUrl})]},n.sourceUrl))})]})})}function K(s){return me[s.reason]??"Not measured"}function L({metric:s,emphasis:n=!1}){if(s.state==="unavailable")return e.jsxs("span",{className:"inline-flex flex-col gap-0.5",children:[e.jsx("span",{className:n?"text-lg font-semibold text-secondary":"text-sm font-medium text-secondary",children:"Not measured"}),e.jsx("span",{className:"text-sm text-secondary",children:K(s)})]});const a=`${Math.round(s.value*100)}%`,c=s.numerator===void 0||s.denominator===void 0?null:`${s.numerator} of ${s.denominator}`;return e.jsxs("span",{className:"inline-flex flex-col gap-0.5 tabular-nums",children:[e.jsx("span",{className:n?"text-lg font-semibold text-heading":"text-sm font-medium text-primary",children:a}),c?e.jsx("span",{className:"text-xs text-muted",children:c}):null]})}function z(s,n,a){return ce({client:B,path:{name:s},query:{scope:"property",targetKey:n,queryClass:a}})}function D(s){return s?.properties.items.at(0)}function fe({branded:s,nonBrand:n,brandedError:a,nonBrandError:c,onRetry:w}){const S=[{queryClass:"branded",row:s,isError:a},{queryClass:"non-brand",row:n,isError:c}];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(C,{text:"Branded questions already contain your name, so an answer engine has an easy path back to you. Non-brand questions describe the need instead, and that is the demand you have to earn. Each row is measured only over the questions assigned to this Property in that class; a class with no assigned question 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 question class"}),e.jsx("thead",{children:e.jsxs("tr",{children:[e.jsx("th",{children:"Question type"}),e.jsx("th",{children:"Mentioned in the answer"}),e.jsx("th",{children:"Cited as a source"})]})}),e.jsx("tbody",{children:S.map(({queryClass:r,row:d,isError:x})=>e.jsxs("tr",{children:[e.jsxs("td",{children:[e.jsx("span",{className:"block font-medium text-heading",children:l[r].headline}),e.jsx("span",{className:"mt-0.5 block text-xs text-muted",children:l[r].technical}),d&&x?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(b,{type:"button",size:"sm",variant:"ghost",className:"h-11 px-3 text-sm md:h-11",onClick:()=>w(r),children:["Retry ",l[r].technical.toLocaleLowerCase()]})]}):null]}),d?e.jsxs(e.Fragment,{children:[e.jsx("td",{children:e.jsx(L,{metric:d.mentionCoverage,emphasis:!0})}),e.jsx("td",{children:e.jsx(L,{metric:d.citationCoverage,emphasis:!0})})]}):x?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 ",l[r].technical.toLocaleLowerCase(),"."]}),e.jsxs(b,{type:"button",size:"sm",variant:"outline",className:"h-11 px-4 text-sm md:h-11",onClick:()=>w(r),children:["Retry ",l[r].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…"})})]})]},r))})]})})]})}function ve({row:s,queryClass:n,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.jsxs("div",{children:[e.jsx("p",{className:"eyebrow eyebrow-soft",children:"By answer engine"}),e.jsxs("h2",{id:"property-providers",className:"text-base font-semibold text-heading",children:["Which engines answer for this Property",e.jsx(C,{text:"Each row is measured over the questions 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 ",l[n].technical.toLocaleLowerCase()," are unavailable. Retry that question 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 ",l[n].technical.toLocaleLowerCase()," for this Property.",s.mentionCoverage.state==="unavailable"?` ${K(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(c=>e.jsxs("tr",{children:[e.jsx("td",{className:"font-medium text-heading",children:c.provider}),e.jsx("td",{children:e.jsx(L,{metric:c.mentionCoverage})}),e.jsx("td",{children:e.jsx(L,{metric:c.citationCoverage})})]},c.provider))})]})})]})}function Ne({questions:s,queryClass:n}){return e.jsxs("section",{"aria-labelledby":"property-questions",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:"Questions"}),e.jsxs("h2",{id:"property-questions",className:"text-base font-semibold text-heading",children:[l[n].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 ",l[n].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:"Questions assigned to this Property"}),e.jsx("thead",{children:e.jsx("tr",{children:e.jsx("th",{children:"Question"})})}),e.jsx("tbody",{children:s.map(a=>e.jsx("tr",{children:e.jsx("td",{className:"text-secondary",children:a})},a))})]})})]})}function we({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.jsxs("div",{children:[e.jsx("p",{className:"eyebrow eyebrow-soft",children:"Pages"}),e.jsxs("h2",{id:"property-urls",className:"text-base font-semibold text-heading",children:["URLs that count as this Property",e.jsx(C,{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(n=>e.jsx("tr",{children:e.jsx("td",{className:"break-all text-secondary",children:n})},n))})]})})]})}function ke(){const{projectName:s,targetKey:n}=te({strict:!1}),[a,c]=v.useState("non-brand"),[w,S]=v.useState(new Set),r=s??"",d=n??"",x=!!r&&!!d,{canWrite:M}=ae(),f=T({...re({client:B,path:{name:r}}),enabled:x}),m=T({...z(r,d,"branded"),enabled:x}),p=T({...z(r,d,"non-brand"),enabled:x}),U=D(m.data),I=D(p.data),u=a==="branded"?m.data:p.data,N=a==="branded"?U:I,_=(a==="branded"?m.isError:p.isError)&&N===void 0,Q=u?.measurement.displayedRunId,P={client:B,path:{name:r},query:{targetKey:d,queryClass:a,shape:ie.answers,limit:F,...Q?{runId:Q}:{}}},i=ne({...oe(P),enabled:x&&u!==void 0,initialPageParam:P,getNextPageParam:t=>t.answers?.nextCursor?{path:P.path,query:{...P.query,cursor:t.answers.nextCursor}}:void 0}),R=f.data?.active??null,j=R?.plan.schemaVersion===2?R.plan:null,W=R!==null&&j===null,E=j?.targets.find(t=>t.stableKey===d)??null,H=v.useMemo(()=>{if(!j)return[];const t=new Map(j.querySnapshots.map(o=>[o.queryId,o.queryText]));return[...new Set(j.assignments.filter(o=>o.targetKey===d&&o.queryClass===a).flatMap(o=>{const h=t.get(o.queryId);return h===void 0?[]:[h]}))].sort((o,h)=>o.localeCompare(h))},[j,d,a]),G=v.useMemo(()=>E?.urlMatchers.map(he)??[],[E]),y=v.useMemo(()=>(i.data?.pages??[]).flatMap(h=>h.answers?.items??[]),[i.data]),$=i.data?.pages[0]?.answers?.totalEstimate??y.length,Y=(i.data?.pages??[]).length>0&&(i.data?.pages??[]).every(t=>t.answers===void 0),Z=i.data?.pages[0]?.measurement.state,A=e.jsxs(q,{to:"/projects/$projectName",params:{projectName:r},className:"inline-flex items-center gap-1 text-xs text-muted hover:text-strong",children:[e.jsx(xe,{className:"size-3.5","aria-hidden":"true"}),"Back to measurement overview"]});if(!x)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(!le("portfolio",de()?.projectTabs))return e.jsx("div",{className:"page-container",children:e.jsx("p",{className:"text-sm text-muted",children:"This view is not available here."})});if(f.isPending&&!f.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 J=f.isError&&f.data===void 0,X=m.isError&&m.data===void 0,ee=p.isError&&p.data===void 0;return J||X&&ee?e.jsxs("div",{className:"page-container space-y-3",children:[A,e.jsx("p",{role:"alert",className:"text-sm text-negative",children:"Could not load this Property."}),e.jsx(b,{type:"button",size:"sm",variant:"outline",className:"h-11 px-4 text-sm md:h-11",onClick:()=>{f.refetch(),m.refetch(),p.refetch()},children:"Try again"})]}):!j||!E?e.jsxs("div",{className:"page-container space-y-3",children:[A,e.jsx("p",{role:"status",className:"text-sm text-secondary",children:j?"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(b,{asChild:!0,type:"button",variant:"outline",className:"h-11 px-4 text-sm md:h-11",children:e.jsx(q,{to:"/projects/$projectName/portfolio",params:{projectName:r},children:M?W?"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:[A,e.jsx("h1",{className:"page-title mt-2",children:E.label}),e.jsxs("p",{className:"page-subtitle",children:["Property in ",r]})]}),e.jsxs("div",{className:"page-header-right",children:[u?e.jsx(g,{tone:O[u.measurement.state].tone,children:O[u.measurement.state].label}):null,N&&N.flags>0?e.jsxs(g,{tone:"caution",children:[N.flags," flagged"]}):null]})]}),e.jsx(fe,{branded:U,nonBrand:I,brandedError:m.isError,nonBrandError:p.isError,onRetry:t=>{t==="branded"?m.refetch():p.refetch()}}),u&&(u.measurement.state==="not_measured"||u.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:M?"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(b,{asChild:!0,type:"button",className:"h-11 px-4 text-sm md:h-11",children:e.jsx(q,{to:"/projects/$projectName",params:{projectName:r},children:M?"Go to measurement overview":"View measurement overview"})})]}):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:"Question type"}),e.jsxs("select",{id:"property-query-class",value:a,onChange:t=>c(t.target.value==="branded"?"branded":"non-brand"),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:l["non-brand"].technical}),e.jsx("option",{value:"branded",children:l.branded.technical})]})]}),e.jsxs("p",{className:"supporting-copy",children:["Everything below is measured over ",l[a].technical.toLocaleLowerCase()," only."]})]}),e.jsx(ve,{row:N,queryClass:a,isError:_}),e.jsx(Ne,{questions:H,queryClass:a}),e.jsx(we,{urls:G}),e.jsxs("section",{"aria-labelledby":"property-evidence",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:"Evidence"}),e.jsxs("h2",{id:"property-evidence",className:"text-base font-semibold text-heading",children:["Answers the engines gave",e.jsx(C,{text:"One row per answer an engine gave for the questions 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. Expand a row for the source URLs the engine returned, this Property's own first."})]})]}),y.length>0?e.jsxs("p",{className:"supporting-copy",children:[y.length," of ",$]}):null]}),_?e.jsxs("p",{className:"text-sm text-secondary",children:["Evidence for ",l[a].technical.toLocaleLowerCase()," is unavailable. Retry that question type above."]}):i.isPending&&y.length===0?e.jsx("p",{className:"text-sm text-secondary",children:"Loading evidence…"}):i.isError&&y.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(b,{type:"button",size:"sm",variant:"outline",className:"h-11 px-4 text-sm md:h-11",onClick:()=>{i.refetch()},children:"Retry evidence"})]}):Z==="not_measured"?e.jsx("p",{className:"text-sm text-secondary",children:"Not measured yet. Run a measurement to collect the answers for this Property."}):Y?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."}):y.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:"overflow-x-auto rounded-md border border-default",children:e.jsxs("table",{className:"evidence-table min-w-[720px]",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:"Question"}),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:y.map(t=>{const o=ue(t),h=w.has(o);return e.jsxs(v.Fragment,{children:[e.jsxs("tr",{children:[e.jsxs("td",{className:"text-secondary",children:[e.jsx("span",{className:"block",children:t.queryText}),e.jsx("span",{className:"mt-1 block text-xs text-muted",children:[t.provider,t.location].filter(Boolean).join(" · ")}),t.historical||t.bridged?e.jsx("span",{className:"mt-1 flex",children:e.jsx(g,{tone:"caution",children:"Historical"})}):null]}),e.jsx("td",{children:e.jsx(je,{row:t})}),e.jsx("td",{children:e.jsx(be,{row:t})}),e.jsx("td",{className:"tabular-nums text-secondary",children:t.cited===null?ye:t.sources.length}),e.jsx("td",{className:"text-right",children:e.jsx(b,{type:"button",size:"sm",variant:"ghost","aria-expanded":h,onClick:()=>S(se=>{const k=new Set(se);return k.delete(o)||k.add(o),k}),children:h?`Hide sources for ${t.queryText}`:`Show sources for ${t.queryText}`})})]}),h?e.jsx("tr",{children:e.jsx("td",{colSpan:5,className:"bg-surface-subtle px-4",children:e.jsx(ge,{row:t})})}):null]},o)})})]})}),i.hasNextPage?e.jsxs("div",{className:"mt-2 flex flex-wrap items-center gap-3 text-sm text-secondary",children:[e.jsxs("span",{children:["Showing ",y.length," of ",$]}),i.isFetchNextPageError?e.jsx("span",{role:"alert",children:"Could not load more evidence."}):null,e.jsx(b,{size:"sm",variant:"outline",className:"h-11 px-4 text-sm md:h-11",disabled:i.isFetchingNextPage,onClick:()=>{i.fetchNextPage()},children:i.isFetchingNextPage?"Loading…":i.isFetchNextPageError?"Retry more evidence":`Show ${F} more`})]}):null]})]})]})}export{ke as MeasurementPropertyPage};
|