@canonry/canonry 5.16.1 → 5.18.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/assets/assets/{AuditHistoryPanel-CnoGPJ5Y.js → AuditHistoryPanel-Di5c6xSa.js} +1 -1
- package/assets/assets/{BacklinksPage-DYe2CYfD.js → BacklinksPage-CZi3sZ-7.js} +1 -1
- package/assets/assets/{HistoryPage-CO-dzLAo.js → HistoryPage-BY7HiZWU.js} +1 -1
- package/assets/assets/MeasurementPropertyPage-D3AdBHpI.js +1 -0
- package/assets/assets/ProjectPage-NyUl1dkF.js +8 -0
- package/assets/assets/{RunRow-CzcaoK_3.js → RunRow-cRjiHQbt.js} +1 -1
- package/assets/assets/{RunsPage-DQWPHDoq.js → RunsPage-DZP_kqJs.js} +1 -1
- package/assets/assets/{SettingsPage-DMtQLrWP.js → SettingsPage-BqJXYCDc.js} +1 -1
- package/assets/assets/{SiteHealthSection-2ljW02xK.js → SiteHealthSection-Brr0C56X.js} +3 -3
- package/assets/assets/{TrafficPage-NFu0LEdk.js → TrafficPage-k5NPSDur.js} +2 -2
- package/assets/assets/{TrafficSourceDetailPage-DbBIzmbL.js → TrafficSourceDetailPage-BKNzWnxA.js} +1 -1
- package/assets/assets/{extract-error-message-pMGpUsIh.js → extract-error-message-Cnvelll0.js} +1 -1
- package/assets/assets/index-Cd_1GknE.js +86 -0
- package/assets/assets/{react-sigma_core.esm.min-CadBie52.js → react-sigma_core.esm.min-CthGjQKl.js} +1 -1
- package/assets/assets/v2-overview-adapter-q2o2MzmG.js +1 -0
- package/assets/index.html +1 -1
- package/dist/{chunk-L36TC6LB.js → chunk-77VHT3JD.js} +29 -3
- package/dist/{chunk-CDQDPUY4.js → chunk-HAABFHXB.js} +2 -2
- package/dist/{chunk-5QK5KHA7.js → chunk-HIFBIDOW.js} +485 -160
- package/dist/{chunk-ZGZSROSR.js → chunk-TMTO2JHU.js} +9 -2
- package/dist/{chunk-JO5HHEJV.js → chunk-X3GFCKUJ.js} +2 -2
- package/dist/{chunk-3YAPVVFN.js → chunk-Y5IDGH5B.js} +52 -17
- package/dist/cli.js +18 -8
- package/dist/{demo-server-QLQUVMKJ.js → demo-server-JBGYZKAI.js} +3 -3
- package/dist/index.d.ts +7 -0
- package/dist/index.js +5 -5
- package/dist/{intelligence-service-EAUKUVVM.js → intelligence-service-EORTVFDF.js} +2 -2
- package/dist/mcp.js +3 -3
- package/package.json +11 -11
- package/assets/assets/MeasurementPropertyPage-smsZFdd6.js +0 -1
- package/assets/assets/ProjectPage-jL3jB2TR.js +0 -8
- package/assets/assets/index-D9NReRHX.js +0 -86
- package/assets/assets/v2-overview-adapter-Oe8hHMAO.js +0 -1
|
@@ -133,7 +133,7 @@ import {
|
|
|
133
133
|
upgradeCaveatFor,
|
|
134
134
|
upgradeCommandFor,
|
|
135
135
|
visibilityReportRequestSchema
|
|
136
|
-
} from "./chunk-
|
|
136
|
+
} from "./chunk-77VHT3JD.js";
|
|
137
137
|
|
|
138
138
|
// src/cli-error.ts
|
|
139
139
|
function isMachineFormat(format) {
|
|
@@ -206,6 +206,7 @@ import { parse, stringify } from "yaml";
|
|
|
206
206
|
import { z } from "zod";
|
|
207
207
|
var dashboardManagedSweepsSchema = z.boolean().nullish();
|
|
208
208
|
var researchAllowViewersSchema = z.boolean().nullish();
|
|
209
|
+
var agentAllowViewersSchema = z.boolean().nullish();
|
|
209
210
|
var researchViewerDailyRunLimitSchema = z.number().int().positive().nullish();
|
|
210
211
|
var dashboardManagedRunKindsSchema = z.array(schedulableRunKindSchema).nullish();
|
|
211
212
|
var agentProviderSchema = agentProviderIdSchema.nullish();
|
|
@@ -476,6 +477,12 @@ Do not use "canonry init --force" for recovery. It replaces credentials without
|
|
|
476
477
|
message: `Invalid config at ${configPath}: agent.model must be a non-empty string or left blank.`
|
|
477
478
|
});
|
|
478
479
|
}
|
|
480
|
+
if (!agentAllowViewersSchema.safeParse(parsed.agent?.allowViewers).success) {
|
|
481
|
+
throw new CliError({
|
|
482
|
+
code: "CONFIG_INVALID",
|
|
483
|
+
message: `Invalid config at ${configPath}: agent.allowViewers must be true, false, or left blank.`
|
|
484
|
+
});
|
|
485
|
+
}
|
|
479
486
|
if (parsed.agent?.model && !parsed.agent?.provider) {
|
|
480
487
|
throw new CliError({
|
|
481
488
|
code: "CONFIG_INVALID",
|
|
@@ -11520,7 +11527,7 @@ var canonryMcpTools = [
|
|
|
11520
11527
|
defineTool({
|
|
11521
11528
|
name: "canonry_measurement_portfolio_summary",
|
|
11522
11529
|
title: "Summarize measured Properties",
|
|
11523
|
-
description: "Start here for best/worst Property mention performance. Defaults to non-brand questions; state the returned queryClass and keep branded comparisons separate unless all was requested. mentionRanking.strongest and .weakest rank every Property with an available mention rate before applying limit, independently of citation availability or an unavailable portfolio aggregate. mentionRanking.excluded names every excluded Property and its reason; flag those separately, never call all mention rankings unavailable because one identity is ambiguous. Report numerator/denominator with each rate. Rates may tie (stable label/key order); this is descriptive coverage, not a confidence-adjusted or unique-winner claim. weakestProperties retains combined mention/citation weaknesses with stored replacement names; markets compares every named market worst-first. Each market is scoped to the displayed run; markets may share Properties, so they never sum to portfolio totals. Reads stored data only; it never starts provider work.",
|
|
11530
|
+
description: "Start here for best/worst Property mention performance. Defaults to non-brand questions; state the returned queryClass and keep branded comparisons separate unless all was requested. mentionRanking.strongest and .weakest rank every Property with an available mention rate before applying limit, independently of citation availability or an unavailable portfolio aggregate. mentionRanking.excluded names every excluded Property and its reason; flag those separately, never call all mention rankings unavailable because one identity is ambiguous. Report numerator/denominator with each rate, and any unattributed count beside it: answers left out of both because their Property identity was unresolved, never not-mentioned answers. Rates may tie (stable label/key order); this is descriptive coverage, not a confidence-adjusted or unique-winner claim. weakestProperties retains combined mention/citation weaknesses with stored replacement names; markets compares every named market worst-first. Each market is scoped to the displayed run; markets may share Properties, so they never sum to portfolio totals. Reads stored data only; it never starts provider work.",
|
|
11524
11531
|
access: "read",
|
|
11525
11532
|
tier: "monitoring",
|
|
11526
11533
|
inputSchema: measurementPortfolioSummaryInputSchema,
|
|
@@ -4,14 +4,14 @@ import {
|
|
|
4
4
|
installSkills,
|
|
5
5
|
loadConfigRaw,
|
|
6
6
|
saveConfigPatch
|
|
7
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-TMTO2JHU.js";
|
|
8
8
|
import {
|
|
9
9
|
PACKAGE_VERSION
|
|
10
10
|
} from "./chunk-AOJU5LKX.js";
|
|
11
11
|
import {
|
|
12
12
|
SKILL_MANIFEST_FILENAME,
|
|
13
13
|
SkillsClients
|
|
14
|
-
} from "./chunk-
|
|
14
|
+
} from "./chunk-77VHT3JD.js";
|
|
15
15
|
|
|
16
16
|
// src/skills-autosync.ts
|
|
17
17
|
import fs from "fs";
|
|
@@ -648,6 +648,7 @@ import {
|
|
|
648
648
|
reportSourceOriginHeadline,
|
|
649
649
|
reportTrendProviderRates,
|
|
650
650
|
reportTruncatedList,
|
|
651
|
+
reportUnattributedAnswers,
|
|
651
652
|
reportVisibilityComparison,
|
|
652
653
|
reportVisibilityEvidence,
|
|
653
654
|
reportVisibilityHistoryLabel,
|
|
@@ -784,7 +785,7 @@ import {
|
|
|
784
785
|
wordpressSchemaDeployResultDtoSchema,
|
|
785
786
|
wordpressSchemaStatusResultDtoSchema,
|
|
786
787
|
wordpressStatusDtoSchema
|
|
787
|
-
} from "./chunk-
|
|
788
|
+
} from "./chunk-77VHT3JD.js";
|
|
788
789
|
|
|
789
790
|
// src/intelligence-service.ts
|
|
790
791
|
import { eq as eq71, desc as desc32, asc as asc12, and as and60, ne as ne11, or as or18, inArray as inArray27, gte as gte18, lte as lte15, isNull as isNull13, sql as sql28, exists } from "drizzle-orm";
|
|
@@ -11681,6 +11682,7 @@ function applyRoleGates(request) {
|
|
|
11681
11682
|
}
|
|
11682
11683
|
function applyScopedWriteGates(request) {
|
|
11683
11684
|
if (!WRITE_METHODS2.has(request.method) || isTransportEnvelopeRoute(request) || request.readSemanticGrant) return;
|
|
11685
|
+
if (isPaidReadRoute(request) && request.principal?.kind === "user") return;
|
|
11684
11686
|
const scopes = principalScopes(request) ?? [];
|
|
11685
11687
|
const restricted = restrictedWriteScopes(scopes);
|
|
11686
11688
|
if (!restricted) return;
|
|
@@ -14561,10 +14563,13 @@ function mentionRate(target, slots, prepared) {
|
|
|
14561
14563
|
if (!status.complete || !status.answerComplete) {
|
|
14562
14564
|
return { numerator: null, denominator: null, rate: null, reason: "incomplete" };
|
|
14563
14565
|
}
|
|
14564
|
-
|
|
14565
|
-
|
|
14566
|
-
|
|
14567
|
-
|
|
14566
|
+
const unattributed = slots.filter((slot) => prepared.observationsBySlot.get(slot.id)?.unknownMentionTargetIds.has(target.id)).length;
|
|
14567
|
+
return attributableMentionRate(numerator, slots.length, unattributed);
|
|
14568
|
+
}
|
|
14569
|
+
function attributableMentionRate(numerator, answered2, unattributed) {
|
|
14570
|
+
const denominator = answered2 - unattributed;
|
|
14571
|
+
if (denominator <= 0) return unavailable("identity-ambiguous");
|
|
14572
|
+
return unattributed > 0 ? { numerator, denominator, rate: numerator / denominator, unattributed } : { numerator, denominator, rate: numerator / denominator };
|
|
14568
14573
|
}
|
|
14569
14574
|
function providersFor(slots) {
|
|
14570
14575
|
return sortedUnique(slots.map((slot) => slot.provider));
|
|
@@ -14755,14 +14760,15 @@ function scopeMentionRate(input, targetIds, slots, answered2, prepared, edges) {
|
|
|
14755
14760
|
const idsByExecution = /* @__PURE__ */ new Map();
|
|
14756
14761
|
for (const edge of edges) if (mentionableIds.has(edge.targetId)) addToSet(idsByExecution, edge.executionId, edge.targetId);
|
|
14757
14762
|
let numerator = 0;
|
|
14763
|
+
let unattributed = 0;
|
|
14758
14764
|
for (const slot of answered2) {
|
|
14759
14765
|
const observation = prepared.observationsBySlot.get(slot.id);
|
|
14760
14766
|
const ids = [...idsByExecution.get(slot.executionId) ?? []];
|
|
14761
14767
|
if (ids.length === 0) return unavailable("aliasless");
|
|
14762
14768
|
if (ids.some((id) => observation.mentionedTargetIds.has(id))) numerator++;
|
|
14763
|
-
else if (ids.some((id) => observation.unknownMentionTargetIds.has(id)))
|
|
14769
|
+
else if (ids.some((id) => observation.unknownMentionTargetIds.has(id))) unattributed++;
|
|
14764
14770
|
}
|
|
14765
|
-
return
|
|
14771
|
+
return attributableMentionRate(numerator, answered2.length, unattributed);
|
|
14766
14772
|
}
|
|
14767
14773
|
function indexedScopeCitationRate(slots, edges, indexes) {
|
|
14768
14774
|
if (slots.length === 0) return unavailable("no-population");
|
|
@@ -14782,9 +14788,9 @@ function targetMentionRate(targets, slots, answered2, indexes) {
|
|
|
14782
14788
|
if (answered2.length !== slots.length) return unavailable("evidence-incomplete");
|
|
14783
14789
|
const mentioned = indexes.mentionedSlotIdsByTargetId.get(mentionable[0].id) ?? /* @__PURE__ */ new Set();
|
|
14784
14790
|
const unknown = indexes.unknownMentionSlotIdsByTargetId.get(mentionable[0].id);
|
|
14785
|
-
|
|
14791
|
+
const unattributed = unknown ? answered2.filter((slot) => unknown.has(slot.id)).length : 0;
|
|
14786
14792
|
const numerator = answered2.filter((slot) => mentioned.has(slot.id)).length;
|
|
14787
|
-
return
|
|
14793
|
+
return attributableMentionRate(numerator, answered2.length, unattributed);
|
|
14788
14794
|
}
|
|
14789
14795
|
function presenceIn(slots, aliases, prepared) {
|
|
14790
14796
|
return slots.filter((slot) => {
|
|
@@ -15469,7 +15475,14 @@ function unavailable2(reason) {
|
|
|
15469
15475
|
}
|
|
15470
15476
|
function coverageMetric(rate2) {
|
|
15471
15477
|
if (rate2.rate === null) return unavailable2(metricReason(rate2.reason));
|
|
15472
|
-
return {
|
|
15478
|
+
return {
|
|
15479
|
+
state: "available",
|
|
15480
|
+
value: rate2.rate,
|
|
15481
|
+
numerator: rate2.numerator,
|
|
15482
|
+
denominator: rate2.denominator,
|
|
15483
|
+
// Answers the mention rate left out because their identity was unresolved.
|
|
15484
|
+
...rate2.unattributed === void 0 ? {} : { unattributed: rate2.unattributed }
|
|
15485
|
+
};
|
|
15473
15486
|
}
|
|
15474
15487
|
function providerRows(property) {
|
|
15475
15488
|
return property.providers.map((row) => ({
|
|
@@ -15631,6 +15644,10 @@ function measurementOutcomeCounts(rows) {
|
|
|
15631
15644
|
continue;
|
|
15632
15645
|
}
|
|
15633
15646
|
const mentioned = (mention.numerator ?? mention.value) > 0;
|
|
15647
|
+
if (!mentioned && mention.unattributed !== void 0) {
|
|
15648
|
+
counts2.notMeasured += 1;
|
|
15649
|
+
continue;
|
|
15650
|
+
}
|
|
15634
15651
|
const cited = (citation.numerator ?? citation.value) > 0;
|
|
15635
15652
|
if (mentioned && cited) counts2.bothSignals += 1;
|
|
15636
15653
|
else if (mentioned) counts2.mentionedOnly += 1;
|
|
@@ -22756,7 +22773,14 @@ function unavailable3(reason) {
|
|
|
22756
22773
|
}
|
|
22757
22774
|
function coverageMetric2(rate2) {
|
|
22758
22775
|
if (rate2.rate === null) return unavailable3(metricReason2(rate2.reason));
|
|
22759
|
-
return {
|
|
22776
|
+
return {
|
|
22777
|
+
state: "available",
|
|
22778
|
+
value: rate2.rate,
|
|
22779
|
+
numerator: rate2.numerator,
|
|
22780
|
+
denominator: rate2.denominator,
|
|
22781
|
+
// Answers the mention rate left out because their identity was unresolved.
|
|
22782
|
+
...rate2.unattributed === void 0 ? {} : { unattributed: rate2.unattributed }
|
|
22783
|
+
};
|
|
22760
22784
|
}
|
|
22761
22785
|
function countMetric2(rate2) {
|
|
22762
22786
|
if (rate2.numerator === null) return unavailable3(metricReason2(rate2.reason));
|
|
@@ -23631,11 +23655,19 @@ function citationForCoverage(candidate, targets, targetKey) {
|
|
|
23631
23655
|
}
|
|
23632
23656
|
function mentionRate2(candidates, targets, targetKey) {
|
|
23633
23657
|
const values = candidates.map((candidate) => targetValues(candidate, targets, targetKey));
|
|
23634
|
-
return
|
|
23635
|
-
|
|
23636
|
-
|
|
23637
|
-
|
|
23638
|
-
|
|
23658
|
+
if (values.length === 0) return unavailable4("no-population");
|
|
23659
|
+
let numerator = 0;
|
|
23660
|
+
let unattributed = 0;
|
|
23661
|
+
for (const value of values) {
|
|
23662
|
+
if (value.mention === true) numerator++;
|
|
23663
|
+
else if (value.mention === null) {
|
|
23664
|
+
if (value.mentionUnavailableReason !== "identity-ambiguous") return unavailable4("evidence-incomplete");
|
|
23665
|
+
unattributed++;
|
|
23666
|
+
}
|
|
23667
|
+
}
|
|
23668
|
+
const denominator = values.length - unattributed;
|
|
23669
|
+
if (denominator === 0) return unavailable4("identity-ambiguous");
|
|
23670
|
+
return unattributed > 0 ? { numerator, denominator, rate: numerator / denominator, unattributed } : { numerator, denominator, rate: numerator / denominator };
|
|
23639
23671
|
}
|
|
23640
23672
|
function answered(candidate) {
|
|
23641
23673
|
return candidate.observation !== null;
|
|
@@ -31466,7 +31498,10 @@ function renderReportHtml(report, opts = {}) {
|
|
|
31466
31498
|
function renderReportVisibility(visibility) {
|
|
31467
31499
|
const populations = visibility.populations.filter((population) => population.queryClass !== "unknown" || population.summary.answerCount > 0);
|
|
31468
31500
|
const historyPopulations = visibility.populations.filter((population) => population.queryClass !== "unknown" || population.trend.some((point) => point.answerCount > 0));
|
|
31469
|
-
const rateCell = (rate2) =>
|
|
31501
|
+
const rateCell = (rate2) => {
|
|
31502
|
+
const unattributed = reportUnattributedAnswers(rate2);
|
|
31503
|
+
return `<td><strong>${escapeHtml2(reportVisibilityRate(rate2))}</strong><p class="muted">${escapeHtml2(reportVisibilityEvidence(rate2))}</p>${unattributed ? `<p class="muted">${escapeHtml2(unattributed)}</p>` : ""}</td>`;
|
|
31504
|
+
};
|
|
31470
31505
|
const headers = (labels) => `<thead><tr>${labels.map((label) => `<th>${escapeHtml2(label)}</th>`).join("")}</tr></thead>`;
|
|
31471
31506
|
const summary3 = `<table class="report-table">${headers([REPORT_VISIBILITY_COPY.queryType, REPORT_VISIBILITY_COPY.queries, REPORT_VISIBILITY_COPY.answers, REPORT_VISIBILITY_COPY.mentioned, REPORT_VISIBILITY_COPY.cited])}<tbody>${populations.map((population) => `<tr><td>${escapeHtml2(reportQueryClassLabel(population.queryClass))}</td><td>${population.summary.queryCount}</td><td>${population.summary.answerCount}</td>${rateCell(population.summary.mentionCoverage)}${rateCell(population.summary.citationCoverage)}</tr>`).join("")}</tbody></table>`;
|
|
31472
31507
|
const trend = `<details><summary>${escapeHtml2(reportVisibilityHistoryLabel(visibility))}</summary><div class="table-scroll"><table class="report-table">${headers([REPORT_VISIBILITY_COPY.date, REPORT_VISIBILITY_COPY.queryType, REPORT_VISIBILITY_COPY.mentioned, REPORT_VISIBILITY_COPY.cited, REPORT_VISIBILITY_COPY.comparison])}<tbody>${historyPopulations.flatMap((population) => population.trend.map((point) => `<tr><td><time datetime="${escapeHtml2(point.createdAt)}">${escapeHtml2(point.createdAt.slice(0, 10))}</time></td><td>${escapeHtml2(reportQueryClassLabel(population.queryClass))}</td>${rateCell(point.mentionCoverage)}${rateCell(point.citationCoverage)}<td>${escapeHtml2(reportVisibilityComparison(point.continuity.state, point.continuity.comparedRunId !== null && !population.trend.some((previous) => previous.runId === point.continuity.comparedRunId)))}</td></tr>`)).join("")}</tbody></table></div></details>`;
|
package/dist/cli.js
CHANGED
|
@@ -35,11 +35,11 @@ import {
|
|
|
35
35
|
trackCliCommandFinished,
|
|
36
36
|
trackEvent,
|
|
37
37
|
waitForServerRuntimeStartup
|
|
38
|
-
} from "./chunk-
|
|
38
|
+
} from "./chunk-HIFBIDOW.js";
|
|
39
39
|
import {
|
|
40
40
|
autoSyncSkills,
|
|
41
41
|
formatAutoSyncNotice
|
|
42
|
-
} from "./chunk-
|
|
42
|
+
} from "./chunk-X3GFCKUJ.js";
|
|
43
43
|
import {
|
|
44
44
|
CliError,
|
|
45
45
|
EXIT_SYSTEM_ERROR,
|
|
@@ -66,13 +66,13 @@ import {
|
|
|
66
66
|
shouldPrintServeSkillsNudge,
|
|
67
67
|
systemError,
|
|
68
68
|
usageError
|
|
69
|
-
} from "./chunk-
|
|
69
|
+
} from "./chunk-TMTO2JHU.js";
|
|
70
70
|
import {
|
|
71
71
|
DEFAULT_DEMO_TRUSTED_PROXIES,
|
|
72
72
|
trustedProxiesProblem,
|
|
73
73
|
trustedProxyProblem
|
|
74
74
|
} from "./chunk-RB2F4D3Z.js";
|
|
75
|
-
import "./chunk-
|
|
75
|
+
import "./chunk-HAABFHXB.js";
|
|
76
76
|
import "./chunk-AOJU5LKX.js";
|
|
77
77
|
import {
|
|
78
78
|
CLOUDFLARE_WORKER_BINDINGS,
|
|
@@ -88,7 +88,7 @@ import {
|
|
|
88
88
|
queries,
|
|
89
89
|
renderReportHtml,
|
|
90
90
|
runs
|
|
91
|
-
} from "./chunk-
|
|
91
|
+
} from "./chunk-Y5IDGH5B.js";
|
|
92
92
|
import {
|
|
93
93
|
AdsDeliverySnapshotStatuses,
|
|
94
94
|
AdsHistoricalCampaignRollupStatuses,
|
|
@@ -110,6 +110,7 @@ import {
|
|
|
110
110
|
RunTriggers,
|
|
111
111
|
TrafficEventKinds,
|
|
112
112
|
TrafficSeriesGranularities,
|
|
113
|
+
UNATTRIBUTED_MENTION_REASON,
|
|
113
114
|
USER_PASSWORD_MIN_LENGTH,
|
|
114
115
|
UserRoles,
|
|
115
116
|
adsActivateTreeRequestSchema,
|
|
@@ -165,6 +166,7 @@ import {
|
|
|
165
166
|
notificationEventSchema,
|
|
166
167
|
queryTrackingCommitRequestSchema,
|
|
167
168
|
queryTrackingPreviewRequestSchema,
|
|
169
|
+
reportUnattributedAnswers,
|
|
168
170
|
researchBatchCreateSchema,
|
|
169
171
|
resolveProviderInput,
|
|
170
172
|
resultsClearRequestSchema,
|
|
@@ -173,7 +175,7 @@ import {
|
|
|
173
175
|
snapshotProviderModeSchema,
|
|
174
176
|
visibilityReportRequestSchema,
|
|
175
177
|
winnabilityClassSchema
|
|
176
|
-
} from "./chunk-
|
|
178
|
+
} from "./chunk-77VHT3JD.js";
|
|
177
179
|
|
|
178
180
|
// src/cli.ts
|
|
179
181
|
import { pathToFileURL } from "url";
|
|
@@ -438,7 +440,7 @@ function parseDemoTrustedProxies(values) {
|
|
|
438
440
|
async function demoCommand(options) {
|
|
439
441
|
const { host, port } = parseDemoListenOptions(options);
|
|
440
442
|
const trustProxy = parseDemoTrustedProxies(options.trustProxy);
|
|
441
|
-
const { createDemoServer } = await import("./demo-server-
|
|
443
|
+
const { createDemoServer } = await import("./demo-server-JBGYZKAI.js");
|
|
442
444
|
const app = await createDemoServer({ trustProxy });
|
|
443
445
|
let stopping = false;
|
|
444
446
|
const stop = () => {
|
|
@@ -10372,8 +10374,12 @@ var METRIC_REASONS = {
|
|
|
10372
10374
|
no_completed_run: "not measured (no completed run)",
|
|
10373
10375
|
no_population: "not measured (no questions of this type)",
|
|
10374
10376
|
evidence_incomplete: "not measured (evidence incomplete)",
|
|
10377
|
+
identity_ambiguous: `not measured (${UNATTRIBUTED_MENTION_REASON.toLowerCase()})`,
|
|
10375
10378
|
not_applicable: "not measured (not applicable)"
|
|
10376
10379
|
};
|
|
10380
|
+
function unattributedText(metric) {
|
|
10381
|
+
return metric.state === "available" ? reportUnattributedAnswers(metric) : null;
|
|
10382
|
+
}
|
|
10377
10383
|
function metricText(metric) {
|
|
10378
10384
|
if (metric.state === "unavailable") return METRIC_REASONS[metric.reason] ?? `not measured (${metric.reason})`;
|
|
10379
10385
|
const percent = `${Math.round(metric.value * 100)}%`;
|
|
@@ -10400,7 +10406,9 @@ function printMeasurementProperty(response) {
|
|
|
10400
10406
|
lines.push(`${response.scope.label} \u2014 ${response.queryClass} questions`);
|
|
10401
10407
|
lines.push(`Measurement: ${response.measurement.state}${response.measurement.displayedRunId ? ` \xB7 run ${response.measurement.displayedRunId}` : ""}`);
|
|
10402
10408
|
lines.push("");
|
|
10403
|
-
|
|
10409
|
+
const mention = row ? row.mentionCoverage : response.metrics.mentionCoverage;
|
|
10410
|
+
const unattributed = unattributedText(mention);
|
|
10411
|
+
lines.push(`Mentioned ${metricText(mention)}${unattributed ? ` \xB7 ${unattributed}` : ""}`);
|
|
10404
10412
|
lines.push(`Cited ${metricText(row ? row.citationCoverage : response.metrics.citationCoverage)}`);
|
|
10405
10413
|
if (row && row.flags > 0) lines.push(`Flagged ${row.flags} ${row.flags === 1 ? "result needs" : "results need"} review`);
|
|
10406
10414
|
if (row && row.providers.length > 0) {
|
|
@@ -10408,6 +10416,8 @@ function printMeasurementProperty(response) {
|
|
|
10408
10416
|
lines.push(`${"Engine".padEnd(14)}${"Mentioned".padEnd(34)}Cited`);
|
|
10409
10417
|
for (const provider of row.providers) {
|
|
10410
10418
|
lines.push(`${provider.provider.padEnd(14)}${metricText(provider.mentionCoverage).padEnd(34)}${metricText(provider.citationCoverage)}`);
|
|
10419
|
+
const providerUnattributed = unattributedText(provider.mentionCoverage);
|
|
10420
|
+
if (providerUnattributed) lines.push(`${"".padEnd(14)}${providerUnattributed}`);
|
|
10411
10421
|
}
|
|
10412
10422
|
}
|
|
10413
10423
|
console.log(lines.join("\n"));
|
|
@@ -4,7 +4,7 @@ import {
|
|
|
4
4
|
import {
|
|
5
5
|
layoutSiteCrawlGraphInput,
|
|
6
6
|
persistSiteCrawlGraphLayout
|
|
7
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-HAABFHXB.js";
|
|
8
8
|
import {
|
|
9
9
|
PACKAGE_VERSION
|
|
10
10
|
} from "./chunk-AOJU5LKX.js";
|
|
@@ -83,7 +83,7 @@ import {
|
|
|
83
83
|
siteCrawlPages,
|
|
84
84
|
siteCrawlSnapshots,
|
|
85
85
|
trafficSources
|
|
86
|
-
} from "./chunk-
|
|
86
|
+
} from "./chunk-Y5IDGH5B.js";
|
|
87
87
|
import {
|
|
88
88
|
RunKinds,
|
|
89
89
|
SiteCrawlFetchStates,
|
|
@@ -104,7 +104,7 @@ import {
|
|
|
104
104
|
measurementPlanV2Schema,
|
|
105
105
|
placementLinkDecision,
|
|
106
106
|
siteAuditPageFactorSchema
|
|
107
|
-
} from "./chunk-
|
|
107
|
+
} from "./chunk-77VHT3JD.js";
|
|
108
108
|
|
|
109
109
|
// src/demo-server.ts
|
|
110
110
|
import { dirname, join as join2 } from "path";
|
package/dist/index.d.ts
CHANGED
|
@@ -316,6 +316,13 @@ interface AgentConfigEntry {
|
|
|
316
316
|
* provider's agent-tier default.
|
|
317
317
|
*/
|
|
318
318
|
model?: string;
|
|
319
|
+
/**
|
|
320
|
+
* Let signed-in viewer accounts use Aero. Off by default. A viewer gets their
|
|
321
|
+
* own in-memory conversation, never the operator's, and every tool call runs
|
|
322
|
+
* with the viewer's own read-only authority. `CANONRY_AGENT_ALLOW_VIEWERS`
|
|
323
|
+
* overrides it; resolved by `resolveAgentAllowViewers`.
|
|
324
|
+
*/
|
|
325
|
+
allowViewers?: boolean | null;
|
|
319
326
|
}
|
|
320
327
|
interface DashboardConfigEntry {
|
|
321
328
|
/**
|
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-HIFBIDOW.js";
|
|
7
7
|
import {
|
|
8
8
|
loadConfig
|
|
9
|
-
} from "./chunk-
|
|
10
|
-
import "./chunk-
|
|
9
|
+
} from "./chunk-TMTO2JHU.js";
|
|
10
|
+
import "./chunk-HAABFHXB.js";
|
|
11
11
|
import "./chunk-AOJU5LKX.js";
|
|
12
|
-
import "./chunk-
|
|
13
|
-
import "./chunk-
|
|
12
|
+
import "./chunk-Y5IDGH5B.js";
|
|
13
|
+
import "./chunk-77VHT3JD.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-X3GFCKUJ.js";
|
|
4
4
|
import {
|
|
5
5
|
createApiClient,
|
|
6
6
|
createCanonryMcpServer
|
|
7
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-TMTO2JHU.js";
|
|
8
8
|
import "./chunk-AOJU5LKX.js";
|
|
9
9
|
import {
|
|
10
10
|
isReadOnlyKey,
|
|
11
11
|
updateCheckEnvOptOut
|
|
12
|
-
} from "./chunk-
|
|
12
|
+
} from "./chunk-77VHT3JD.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": "5.
|
|
3
|
+
"version": "5.18.0",
|
|
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": [
|
|
@@ -87,29 +87,29 @@
|
|
|
87
87
|
"tsup": "^8.5.1",
|
|
88
88
|
"tsx": "^4.19.0",
|
|
89
89
|
"@ainyc/canonry-web": "0.0.0",
|
|
90
|
-
"@ainyc/canonry-api-client": "0.0.0",
|
|
91
90
|
"@ainyc/canonry-api-routes": "0.0.0",
|
|
92
|
-
"@ainyc/canonry-
|
|
93
|
-
"@ainyc/canonry-db": "0.0.0",
|
|
91
|
+
"@ainyc/canonry-api-client": "0.0.0",
|
|
94
92
|
"@ainyc/canonry-config": "0.0.0",
|
|
93
|
+
"@ainyc/canonry-db": "0.0.0",
|
|
94
|
+
"@ainyc/canonry-contracts": "0.0.0",
|
|
95
95
|
"@ainyc/canonry-integration-bing": "0.0.0",
|
|
96
96
|
"@ainyc/canonry-integration-cloud-run": "0.0.0",
|
|
97
97
|
"@ainyc/canonry-integration-cloudflare-queue": "0.0.0",
|
|
98
|
-
"@ainyc/canonry-integration-cloudflare-worker": "0.0.0",
|
|
99
98
|
"@ainyc/canonry-integration-google": "0.0.0",
|
|
100
|
-
"@ainyc/canonry-integration-
|
|
99
|
+
"@ainyc/canonry-integration-cloudflare-worker": "0.0.0",
|
|
101
100
|
"@ainyc/canonry-integration-google-places": "0.0.0",
|
|
102
101
|
"@ainyc/canonry-integration-commoncrawl": "0.0.0",
|
|
102
|
+
"@ainyc/canonry-integration-google-ads": "0.0.0",
|
|
103
103
|
"@ainyc/canonry-integration-google-tag-manager": "0.0.0",
|
|
104
|
+
"@ainyc/canonry-integration-google-business-profile": "0.0.0",
|
|
105
|
+
"@ainyc/canonry-integration-openai-ads": "0.0.0",
|
|
104
106
|
"@ainyc/canonry-integration-wordpress": "0.0.0",
|
|
105
|
-
"@ainyc/canonry-integration-google-ads": "0.0.0",
|
|
106
107
|
"@ainyc/canonry-integration-traffic": "0.0.0",
|
|
107
|
-
"@ainyc/canonry-integration-openai-ads": "0.0.0",
|
|
108
|
-
"@ainyc/canonry-provider-claude": "0.0.0",
|
|
109
|
-
"@ainyc/canonry-provider-cdp": "0.0.0",
|
|
110
108
|
"@ainyc/canonry-intelligence": "0.0.0",
|
|
111
|
-
"@ainyc/canonry-provider-
|
|
109
|
+
"@ainyc/canonry-provider-cdp": "0.0.0",
|
|
110
|
+
"@ainyc/canonry-provider-claude": "0.0.0",
|
|
112
111
|
"@ainyc/canonry-provider-local": "0.0.0",
|
|
112
|
+
"@ainyc/canonry-provider-gemini": "0.0.0",
|
|
113
113
|
"@ainyc/canonry-provider-openai": "0.0.0",
|
|
114
114
|
"@ainyc/canonry-provider-perplexity": "0.0.0"
|
|
115
115
|
},
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{D as fe,k as Ne,l as we,r as b,u as L,C as Pe,j as e,L as I}from"./vendor-tanstack-ZXXkndVj.js";import{dQ as Ce,eb as Ee,dJ as Le,dH as Me,x as Ae,e0 as Se,dX as z,fe as Re,ff as ke,j as M,fg as qe,B as g,I as P,T as w,az as ae,aA as ne,ed as H,fh as Te,fi as Ie,fj as Ue,A as Be}from"./index-D9NReRHX.js";import{j as $e,o as _e}from"./ChartPrimitives-BQC2VH0O.js";import{m as Ve,a as ce,M as Oe,A as Qe}from"./v2-overview-adapter-Oe8hHMAO.js";import{Z as Fe}from"./vendor-lucide-N6vOpZmh.js";import"./vendor-radix-twS1M3FF.js";import"./vendor-recharts-llkUFBGR.js";import"./vendor-markdown-B4giJcws.js";import"./vendor-yaml-GWJz5H2G.js";const re=50,p={branded:{headline:"When they know your name",technical:"Branded queries"},"non-brand":{headline:"When they don't",technical:"Non-brand queries"}},Ke={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",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 ze(s){return[...s].sort((t,a)=>+(a.classification==="assigned")-+(t.classification==="assigned"))}function He(s){return`${s.expectedSlotId}:${s.usageEdgeId}`}function De({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 We="—";function Ge({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 Ye({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:[ce," (",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:ze(s.sources).map(t=>{const a=Be(t.sourceUrl);return e.jsxs("tr",{children:[e.jsx("td",{children:e.jsx(w,{tone:oe[t.classification].tone,children:oe[t.classification].label})}),e.jsx("td",{className:"break-all text-secondary",children:a?e.jsx("a",{href:a,target:"_blank",rel:"noopener noreferrer",className:"text-link underline",children:t.sourceUrl}):t.sourceUrl})]},t.sourceUrl)})})]})})]})}function Ze({project:s,targetKey:t,row:a}){const r=L({...Ue({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 o=r.data?.answer;return o==null||o.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(Qe,{headingLevel:4,copyable:!0,children:o})})}function B(s){return Ke[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=`${Math.round(s.value*100)}%`,r=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: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]})}function le(s,t,a){return Te({client:M,path:{name:s},query:{scope:"property",targetKey:t,queryClass:a}})}function de(s){return s?.properties.items.at(0)}function Je({measuredAt:s,unmeasuredReason:t,queryClass:a}){const r=s===void 0?null:s===null?"No completed sweep yet":`Measured ${$e(_e(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?` · ${p[a].technical.toLocaleLowerCase()} only`:""]})}function Xe({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(H(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 T({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 j=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:j==="Not measured"?"":j})]})}const r=Math.round(t.value*100),o=t.numerator===void 0||t.denominator===void 0?null:`${t.numerator} of ${t.denominator}`;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,e.jsx("span",{className:"text-faint",children:"%"})]}),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:`${r}%`}})}),e.jsx("p",{className:"aeo-hero-row-detail tabular-nums",children:o??""})]})}function es({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(T,{label:"Mentioned",metric:t?.mentionCoverage,failed:r}),e.jsx(T,{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(T,{label:"Mentioned",metric:s?.mentionCoverage,failed:a}),e.jsx(T,{label:"Cited",metric:s?.citationCoverage,failed:a})]})]})]})}function ss({branded:s,nonBrand:t,brandedError:a,nonBrandError:r,onRetry:o}){const j=[{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:j.map(({queryClass:l,row:d,isError:c})=>e.jsxs("tr",{children:[e.jsxs("td",{children:[e.jsx("span",{className:"block font-medium text-heading",children:p[l].headline}),e.jsx("span",{className:"mt-0.5 block text-xs text-muted",children:p[l].technical}),d&&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:()=>o(l),children:["Retry ",p[l].technical.toLocaleLowerCase()]})]}):null]}),d?e.jsxs(e.Fragment,{children:[e.jsx("td",{children:e.jsx(U,{metric:d.mentionCoverage,emphasis:!0})}),e.jsx("td",{children:e.jsx(U,{metric:d.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 ",p[l].technical.toLocaleLowerCase(),"."]}),e.jsxs(g,{type:"button",size:"sm",variant:"outline",className:"h-11 px-4 text-sm md:h-11",onClick:()=>o(l),children:["Retry ",p[l].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…"})})]})]},l))})]})})]})}function ts({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 ",p[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 ",p[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 as(s){const t=s.questions.join(" · ");return s.questionsTruncated?`${t} +${s.questionTotal-s.questions.length} more`:t}function ns({project:s,targetKey:t,queryClass:a}){const r=L({...Ie({client:M,path:{name:s},query:{targetKey:t,queryClass:a}})});if(r.isPending||r.isError)return null;const o=r.data?.competitors??[],j=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."})]})}),o.length>0?e.jsxs("p",{className:"supporting-copy",children:[r.data?.total??o.length," named"]}):null]}),o.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:o.map(l=>e.jsxs("tr",{children:[e.jsx("td",{className:"text-strong",children:l.name}),e.jsx("td",{className:"tabular-nums text-secondary",children:l.occurrences}),e.jsxs("td",{className:"text-secondary",children:[l.providers.join(", "),l.providersTruncated?` +${l.providerTotal-l.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:l.questionTotal}),e.jsx(P,{text:as(l)})]})})]},l.name))})]})}),j?.state==="available"?e.jsxs("p",{className:"supporting-copy mt-2",children:[j.targetMissResults," of ",j.answeredResults," answers to ",p[a].technical.toLocaleLowerCase()," did not name this Property."]}):null]})]})}function rs({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:[p[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 ",p[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 is({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 os(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 ${Oe.allMarkets.toLocaleLowerCase()} and answer engines.`}function bs(){const{projectName:s,targetKey:t}=fe({strict:!1}),a=Ne(),r=we({strict:!1}),o=b.useMemo(()=>Ce(r),[r]),[j,l]=b.useState(new Set),d=s??"",c=t??"",D=!!d&&!!c,W=b.useMemo(()=>Ee("portfolio",Le(Me())),[]),A=D&&W,{canWrite:$}=Ae(),C=L({...Se({client:M,path:{name:d}}),enabled:A}),G=C.data?.active?.plan,_=G?.schemaVersion===2?G:null,V=o.queryClass==="branded"||o.queryClass==="non-brand"?o.queryClass:null,Y=n=>_?.assignments.some(i=>i.targetKey===c&&i.queryClass===n)??!1,h=V??(!Y("non-brand")&&Y("branded")?"branded":"non-brand");b.useEffect(()=>{!_||V||a({to:".",replace:!0,search:n=>z(n,{queryClass:h})})},[_,V,h,a]);const v=L({...le(d,c,"branded"),enabled:A}),f=L({...le(d,c,"non-brand"),enabled:A}),O=de(v.data),Q=de(f.data),y=h==="branded"?v.data:f.data,E=h==="branded"?O:Q,Z=(h==="branded"?v.isError:f.isError)&&E===void 0,S=y?.measurement.displayedRunId;Re(d,{view:"property",selection:{mode:"advanced",scope:"property",scopeKey:c,queryClass:h,limit:10,...S?{runId:S}:{}}});const he=E?.mentionCoverage.state==="unavailable"?B(E.mentionCoverage):void 0,me=y===void 0?void 0:y.measurement.completedAt??null,R={client:M,path:{name:d},query:{targetKey:c,queryClass:h,shape:ke.answers,limit:re,...S?{runId:S}:{}}},m=Pe({...qe(R),enabled:A&&y!==void 0,initialPageParam:R,getNextPageParam:n=>n.answers?.nextCursor?{path:R.path,query:{...R.query,cursor:n.answers.nextCursor}}:void 0}),F=C.data?.active??null,u=F?.plan.schemaVersion===2?F.plan:null,xe=F!==null&&u===null,k=u?.targets.find(n=>n.stableKey===c)??null,J=os(o,u?.reportingScopes?.find(n=>n.stableKey===o.marketKey)?.label),pe=b.useMemo(()=>{if(!u)return[];const n=new Map(u.querySnapshots.map(i=>[i.queryId,i.queryText]));return[...new Set(u.assignments.filter(i=>i.targetKey===c&&i.queryClass===h).flatMap(i=>{const x=n.get(i.queryId);return x===void 0?[]:[x]}))].sort((i,x)=>i.localeCompare(x))},[u,c,h]),ue=b.useMemo(()=>k?.urlMatchers.map(Ve)??[],[k]),je=b.useMemo(()=>u?.groups.filter(n=>n.targetKeys.includes(c))??[],[u,c]),N=b.useMemo(()=>(m.data?.pages??[]).flatMap(x=>x.answers?.items??[]),[m.data]),X=m.data?.pages[0]?.answers?.totalEstimate??N.length,ye=(m.data?.pages??[]).length>0&&(m.data?.pages??[]).every(n=>n.answers===void 0),be=m.data?.pages[0]?.measurement.state,q=e.jsxs(I,{to:"/projects/$projectName",params:{projectName:d},search:H,className:"inline-flex items-center gap-1 text-xs text-muted hover:text-strong",children:[e.jsx(Fe,{className:"size-3.5","aria-hidden":"true"}),"Back to AI Visibility"]});if(!D)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:[q,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 ge=C.isError&&C.data===void 0,ee=v.isError&&v.data===void 0,se=f.isError&&f.data===void 0;return ge||ee&&se?e.jsxs("div",{className:"page-container space-y-3",children:[q,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"})]}):!u||!k?e.jsxs("div",{className:"page-container space-y-3",children:[q,e.jsx("p",{role:"status",className:"text-sm text-secondary",children:u?"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:d},children:$?xe?"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:[q,e.jsx("h1",{className:"page-title mt-2",children:k.label}),e.jsxs("p",{className:"page-subtitle",children:["Property in ",d,J?e.jsxs(e.Fragment,{children:[" · Filters not applied ",e.jsx(P,{text:J})]}):null]})]}),e.jsxs("div",{className:"page-header-right",children:[y?e.jsx(w,{tone:ie[y.measurement.state].tone,children:ie[y.measurement.state].label}):null,E&&E.flags>0?e.jsxs(w,{tone:"caution",children:[E.flags," flagged"]}):null]})]}),e.jsx(es,{branded:O,nonBrand:Q,brandedFailed:ee,nonBrandFailed:se}),e.jsx(ss,{branded:O,nonBrand:Q,brandedError:v.isError,nonBrandError:f.isError,onRetry:n=>{n==="branded"?v.refetch():f.refetch()}}),y&&(y.measurement.state==="not_measured"||y.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:d},search:H,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 i=n.target.value==="branded"?"branded":"non-brand";a({to:".",search:x=>z(x,{queryClass:i})})},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:p["non-brand"].technical}),e.jsx("option",{value:"branded",children:p.branded.technical})]})]}),e.jsx(Je,{measuredAt:me,unmeasuredReason:he,queryClass:h})]}),e.jsx(ts,{row:E,queryClass:h,isError:Z}),e.jsx(ns,{project:d,targetKey:c,queryClass:h}),e.jsx(rs,{questions:pe,queryClass:h}),e.jsx(is,{urls:ue}),e.jsx(Xe,{project:d,groups:je}),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 ",p[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"})]}):be==="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."}):ye?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 i=He(n),x=j.has(i),te=`property-answer-${encodeURIComponent(i)}`;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(De,{row:n})]}),e.jsxs("td",{children:[e.jsx("span",{className:"property-evidence-mobile-label","aria-hidden":"true",children:"Cited"}),e.jsx(Ge,{row:n})]}),e.jsxs("td",{className:"tabular-nums text-secondary",children:[e.jsx("span",{className:"property-evidence-mobile-label","aria-hidden":"true",children:ce}),n.cited===null?We: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:()=>l(ve=>{const K=new Set(ve);return K.delete(i)||K.add(i),K}),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(Ze,{project:d,targetKey:c,row:n}),e.jsx(Ye,{row:n})]})}):null]},i)})})]})}),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,bs as MeasurementPropertyPage};
|