@canonry/canonry 6.3.1 → 7.1.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/README.md +3 -3
- package/assets/agent-workspace/skills/aero/SKILL.md +2 -2
- package/assets/agent-workspace/skills/aero/references/reporting.md +26 -23
- package/assets/agent-workspace/skills/canonry/references/canonry-cli.md +55 -22
- package/assets/agent-workspace/skills/canonry/references/server-side-traffic.md +17 -6
- package/assets/assets/AuditHistoryPanel-CZWzgyrD.js +1 -0
- package/assets/assets/{BacklinksPage-aBcxpN_9.js → BacklinksPage-D23A-ahd.js} +1 -1
- package/assets/assets/ChartPrimitives-CYlrwLJs.js +1 -0
- package/assets/assets/{HistoryPage-PoBuxiY_.js → HistoryPage-BKGVxmNz.js} +1 -1
- package/assets/assets/MeasurementPropertyPage-BSxn6_RB.js +1 -0
- package/assets/assets/ProjectPage-D9W8G_1m.js +8 -0
- package/assets/assets/{RunsPage-CHHxOpzo.js → RunsPage-CeBBjLSE.js} +1 -1
- package/assets/assets/{SettingsPage-CNKnrLXC.js → SettingsPage-Jp5Yp4cz.js} +1 -1
- package/assets/assets/SiteHealthSection-DzVegBeN.js +4 -0
- package/assets/assets/{TrafficPage-CY-ibXnb.js → TrafficPage-B66AYwWk.js} +2 -2
- package/assets/assets/{TrafficSourceDetailPage-BgiPXubs.js → TrafficSourceDetailPage-CXtq1yES.js} +1 -1
- package/assets/assets/{extract-error-message-H1dzzfBP.js → extract-error-message-BVa0lOze.js} +1 -1
- package/assets/assets/index-CMe_-fAB.css +1 -0
- package/assets/assets/index-DuhS0WLM.js +86 -0
- package/assets/assets/{react-sigma_core.esm.min-uiYtR_DU.js → react-sigma_core.esm.min-60drsJa6.js} +1 -1
- package/assets/assets/v2-overview-adapter-CLUi2Lkv.js +1 -0
- package/assets/assets/{vendor-recharts-llkUFBGR.js → vendor-recharts-D-cUuLZo.js} +1 -1
- package/assets/index.html +3 -3
- package/dist/{chunk-4WZUR7XX.js → chunk-22R5E5CY.js} +101 -192
- package/dist/{chunk-DERWXLHX.js → chunk-2OQ6D26U.js} +66 -20
- package/dist/{chunk-5GY5WBAF.js → chunk-IAMECH2N.js} +3 -3
- package/dist/{chunk-ZZEPF3A5.js → chunk-MTSFSXCG.js} +83 -19
- package/dist/{chunk-5FYTFE5T.js → chunk-U2S5ABOR.js} +2 -2
- package/dist/{chunk-7CVTTQRV.js → chunk-VDX3LYKL.js} +4460 -8332
- package/dist/{chunk-EV5G5QRR.js → chunk-YGHPT5B2.js} +1475 -3002
- package/dist/cli.js +240 -178
- package/dist/{demo-server-AIFR77TP.js → demo-server-TIMYQLXS.js} +5 -14
- package/dist/index.js +6 -6
- package/dist/{intelligence-service-SYISPW25.js → intelligence-service-YCMRTVCI.js} +2 -2
- package/dist/mcp.js +4 -4
- package/package.json +15 -15
- package/assets/assets/AuditHistoryPanel-BUYWIjlG.js +0 -1
- package/assets/assets/ChartPrimitives-B5okB5g-.js +0 -1
- package/assets/assets/MeasurementPropertyPage-DyjyqHac.js +0 -1
- package/assets/assets/ProjectPage-Mmv5YW-K.js +0 -8
- package/assets/assets/SiteHealthSection-C9RivT7G.js +0 -4
- package/assets/assets/index-C17E5ZcA.css +0 -1
- package/assets/assets/index-DSCun3I9.js +0 -86
- package/assets/assets/v2-overview-adapter-BQokN2eb.js +0 -1
package/assets/index.html
CHANGED
|
@@ -12,14 +12,14 @@
|
|
|
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-DuhS0WLM.js"></script>
|
|
16
16
|
<link rel="modulepreload" crossorigin href="./assets/vendor-tanstack-ZXXkndVj.js">
|
|
17
17
|
<link rel="modulepreload" crossorigin href="./assets/vendor-radix-twS1M3FF.js">
|
|
18
|
-
<link rel="modulepreload" crossorigin href="./assets/vendor-recharts-
|
|
18
|
+
<link rel="modulepreload" crossorigin href="./assets/vendor-recharts-D-cUuLZo.js">
|
|
19
19
|
<link rel="modulepreload" crossorigin href="./assets/vendor-lucide-N6vOpZmh.js">
|
|
20
20
|
<link rel="modulepreload" crossorigin href="./assets/vendor-markdown-B4giJcws.js">
|
|
21
21
|
<link rel="modulepreload" crossorigin href="./assets/vendor-yaml-GWJz5H2G.js">
|
|
22
|
-
<link rel="stylesheet" crossorigin href="./assets/index-
|
|
22
|
+
<link rel="stylesheet" crossorigin href="./assets/index-CMe_-fAB.css">
|
|
23
23
|
</head>
|
|
24
24
|
<body>
|
|
25
25
|
<div id="root"></div>
|
|
@@ -17,23 +17,24 @@ import {
|
|
|
17
17
|
resolveOperatorApiKeyIds,
|
|
18
18
|
resolveSentimentInstallConfig,
|
|
19
19
|
runWithUsageTags,
|
|
20
|
+
saveConfig,
|
|
20
21
|
saveConfigPatch,
|
|
21
22
|
sentimentInstallReadiness
|
|
22
|
-
} from "./chunk-
|
|
23
|
+
} from "./chunk-MTSFSXCG.js";
|
|
23
24
|
import {
|
|
24
25
|
computeFactorAverages,
|
|
25
26
|
deleteSiteCrawlGraphLayout,
|
|
26
27
|
persistSiteCrawlGraphLayout,
|
|
27
28
|
prepareSiteCrawlGraphLayout,
|
|
28
29
|
recordedSharePct
|
|
29
|
-
} from "./chunk-
|
|
30
|
+
} from "./chunk-U2S5ABOR.js";
|
|
30
31
|
import {
|
|
31
32
|
CanonryMcpToolNames,
|
|
32
33
|
CliError,
|
|
33
34
|
PACKAGE_VERSION,
|
|
34
35
|
canonryMcpTools,
|
|
35
36
|
isMachineFormat
|
|
36
|
-
} from "./chunk-
|
|
37
|
+
} from "./chunk-2OQ6D26U.js";
|
|
37
38
|
import {
|
|
38
39
|
CC_CACHE_DIR,
|
|
39
40
|
DUCKDB_SPEC,
|
|
@@ -161,6 +162,7 @@ import {
|
|
|
161
162
|
newerFullSweep,
|
|
162
163
|
nextRunFromCron,
|
|
163
164
|
nextRunFromSchedule,
|
|
165
|
+
notProbeRun,
|
|
164
166
|
notifications,
|
|
165
167
|
parseCookieHeader,
|
|
166
168
|
parseJsonColumn,
|
|
@@ -214,7 +216,7 @@ import {
|
|
|
214
216
|
siteLivenessState,
|
|
215
217
|
toAlertView,
|
|
216
218
|
usageCounters
|
|
217
|
-
} from "./chunk-
|
|
219
|
+
} from "./chunk-VDX3LYKL.js";
|
|
218
220
|
import {
|
|
219
221
|
AGENT_MEMORY_VALUE_MAX_BYTES,
|
|
220
222
|
AGENT_NONE,
|
|
@@ -330,6 +332,7 @@ import {
|
|
|
330
332
|
effectiveBrandNames,
|
|
331
333
|
effectiveDomains,
|
|
332
334
|
embedClientConfigForRequest,
|
|
335
|
+
embedProjectTabsError,
|
|
333
336
|
extractProviderHttpStatus,
|
|
334
337
|
factorStatusFromScore,
|
|
335
338
|
filterCapturedCitedUrls,
|
|
@@ -375,6 +378,7 @@ import {
|
|
|
375
378
|
normalizeAgentSlug,
|
|
376
379
|
normalizeIdTokens,
|
|
377
380
|
normalizeMeasurementExecutionQueryText,
|
|
381
|
+
normalizeProjectDomain,
|
|
378
382
|
normalizeServedModel,
|
|
379
383
|
normalizeSiteAuditRunRequest,
|
|
380
384
|
normalizeUrlPath,
|
|
@@ -420,7 +424,7 @@ import {
|
|
|
420
424
|
visibilityReportRequestSchema,
|
|
421
425
|
winnabilityClassLabel,
|
|
422
426
|
withRetry
|
|
423
|
-
} from "./chunk-
|
|
427
|
+
} from "./chunk-YGHPT5B2.js";
|
|
424
428
|
|
|
425
429
|
// src/runtime-context.ts
|
|
426
430
|
function cliRuntimeContext(env = process.env, stdio = process) {
|
|
@@ -440,9 +444,6 @@ var TELEMETRY_ENDPOINT = "https://canonry.ai/api/telemetry";
|
|
|
440
444
|
var TIMEOUT_MS = 3e3;
|
|
441
445
|
var ANON_ID_ENV_VAR = "CANONRY_ANONYMOUS_ID";
|
|
442
446
|
var ANON_ID_PATTERN = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
|
|
443
|
-
function shouldDropTelemetryEvent(event, properties) {
|
|
444
|
-
return isGhostTelemetryEvent(event, properties);
|
|
445
|
-
}
|
|
446
447
|
function bucketCliCommandDuration(durationMs) {
|
|
447
448
|
const duration = Number.isFinite(durationMs) ? Math.max(0, durationMs) : 0;
|
|
448
449
|
if (duration < 1e3) return "under_1s";
|
|
@@ -486,7 +487,7 @@ function setTelemetrySource(source) {
|
|
|
486
487
|
function resolveTelemetryStatus(input) {
|
|
487
488
|
const base = {
|
|
488
489
|
configuredEnabled: input.configuredEnabled,
|
|
489
|
-
...input.anonymousId ? { anonymousId:
|
|
490
|
+
...input.anonymousId ? { anonymousId: maskTelemetryAnonymousId(input.anonymousId) } : {},
|
|
490
491
|
target: "local"
|
|
491
492
|
};
|
|
492
493
|
if (input.canonryTelemetryDisabled === "1") {
|
|
@@ -501,9 +502,6 @@ function resolveTelemetryStatus(input) {
|
|
|
501
502
|
if (input.configState === "unavailable") return { ...base, enabled: true, reason: "CONFIG_UNAVAILABLE" };
|
|
502
503
|
return { ...base, enabled: true, reason: "enabled" };
|
|
503
504
|
}
|
|
504
|
-
function maskAnonymousId(value) {
|
|
505
|
-
return maskTelemetryAnonymousId(value);
|
|
506
|
-
}
|
|
507
505
|
function getTelemetryStatus() {
|
|
508
506
|
const env = {
|
|
509
507
|
canonryTelemetryDisabled: process.env.CANONRY_TELEMETRY_DISABLED,
|
|
@@ -629,6 +627,10 @@ function detectAndTrackUpgrade() {
|
|
|
629
627
|
function trackEvent(event, properties, options) {
|
|
630
628
|
void deliverEvent(event, properties, options);
|
|
631
629
|
}
|
|
630
|
+
function recordDashboardEvent(event) {
|
|
631
|
+
const { event: eventName, eventId, ...properties } = event;
|
|
632
|
+
trackEvent(eventName, properties, { source: "dashboard", eventId: String(eventId) });
|
|
633
|
+
}
|
|
632
634
|
function setTelemetryPreference(enabled, method) {
|
|
633
635
|
loadConfig();
|
|
634
636
|
const announce = !enabled && isTelemetryEnabled();
|
|
@@ -637,7 +639,7 @@ function setTelemetryPreference(enabled, method) {
|
|
|
637
639
|
}
|
|
638
640
|
function deliverEvent(event, properties, options, delivery = {}) {
|
|
639
641
|
if (!delivery.preferenceChecked && !isTelemetryEnabled()) return Promise.resolve();
|
|
640
|
-
if (
|
|
642
|
+
if (isGhostTelemetryEvent(event, properties)) return Promise.resolve();
|
|
641
643
|
const anonymousId = getOrCreateAnonymousId();
|
|
642
644
|
if (!anonymousId) return Promise.resolve();
|
|
643
645
|
const payload = {
|
|
@@ -890,92 +892,6 @@ var GOOGLE_ADS_MAX_CUSTOMER_CLIENTS = 1e3;
|
|
|
890
892
|
var GOOGLE_ADS_DEFAULT_CUSTOMER_CLIENT_DEPTH = 1;
|
|
891
893
|
var GOOGLE_ADS_MAX_CUSTOMER_CLIENT_DEPTH = 10;
|
|
892
894
|
|
|
893
|
-
// ../integration-google-ads/src/goal-semantics.ts
|
|
894
|
-
function addInclusion(included, action, inclusion) {
|
|
895
|
-
const existing = included.get(action.resourceName);
|
|
896
|
-
if (existing) {
|
|
897
|
-
existing.includedBy.push(inclusion);
|
|
898
|
-
return;
|
|
899
|
-
}
|
|
900
|
-
included.set(action.resourceName, { conversionAction: action, includedBy: [inclusion] });
|
|
901
|
-
}
|
|
902
|
-
function resolveEffectiveCampaignGoalInputs(inputs) {
|
|
903
|
-
const actions = inputs.conversionActions.map((row) => row.conversionAction);
|
|
904
|
-
const actionsByResource = new Map(actions.map((action) => [action.resourceName, action]));
|
|
905
|
-
const customGoalsByResource = new Map(
|
|
906
|
-
inputs.customGoals.map((row) => [row.customConversionGoal.resourceName, row.customConversionGoal])
|
|
907
|
-
);
|
|
908
|
-
return inputs.campaignConfigs.map((row) => {
|
|
909
|
-
const config = row.conversionGoalCampaignConfig;
|
|
910
|
-
let categoryGoalSource = "UNKNOWN";
|
|
911
|
-
let categoryOriginGoals = [];
|
|
912
|
-
if (config.goalConfigLevel === "CUSTOMER") {
|
|
913
|
-
categoryGoalSource = "CUSTOMER";
|
|
914
|
-
categoryOriginGoals = inputs.customerGoals.map(({ customerConversionGoal: goal }) => ({
|
|
915
|
-
resourceName: goal.resourceName,
|
|
916
|
-
source: "CUSTOMER",
|
|
917
|
-
category: goal.category,
|
|
918
|
-
origin: goal.origin,
|
|
919
|
-
biddable: goal.biddable === true
|
|
920
|
-
}));
|
|
921
|
-
} else if (config.goalConfigLevel === "CAMPAIGN") {
|
|
922
|
-
categoryGoalSource = "CAMPAIGN";
|
|
923
|
-
categoryOriginGoals = inputs.campaignGoals.filter(({ campaignConversionGoal: goal }) => goal.campaign === config.campaign).map(({ campaignConversionGoal: goal }) => ({
|
|
924
|
-
resourceName: goal.resourceName,
|
|
925
|
-
source: "CAMPAIGN",
|
|
926
|
-
category: goal.category,
|
|
927
|
-
origin: goal.origin,
|
|
928
|
-
biddable: goal.biddable === true
|
|
929
|
-
}));
|
|
930
|
-
}
|
|
931
|
-
const included = /* @__PURE__ */ new Map();
|
|
932
|
-
for (const goal of categoryOriginGoals) {
|
|
933
|
-
if (!goal.biddable) continue;
|
|
934
|
-
for (const action of actions) {
|
|
935
|
-
if (action.primaryForGoal !== false && action.category === goal.category && action.origin === goal.origin) {
|
|
936
|
-
addInclusion(included, action, {
|
|
937
|
-
source: goal.source === "CUSTOMER" ? "CUSTOMER_GOAL" : "CAMPAIGN_GOAL",
|
|
938
|
-
goalResourceName: goal.resourceName,
|
|
939
|
-
category: goal.category,
|
|
940
|
-
origin: goal.origin
|
|
941
|
-
});
|
|
942
|
-
}
|
|
943
|
-
}
|
|
944
|
-
}
|
|
945
|
-
let customGoal = null;
|
|
946
|
-
let missingCustomGoalResourceName;
|
|
947
|
-
const missingConversionActionResourceNames = [];
|
|
948
|
-
if (config.goalConfigLevel === "CAMPAIGN" && config.customConversionGoal) {
|
|
949
|
-
customGoal = customGoalsByResource.get(config.customConversionGoal) ?? null;
|
|
950
|
-
if (!customGoal) {
|
|
951
|
-
missingCustomGoalResourceName = config.customConversionGoal;
|
|
952
|
-
} else {
|
|
953
|
-
for (const resourceName of customGoal.conversionActions ?? []) {
|
|
954
|
-
const action = actionsByResource.get(resourceName);
|
|
955
|
-
if (!action) {
|
|
956
|
-
missingConversionActionResourceNames.push(resourceName);
|
|
957
|
-
continue;
|
|
958
|
-
}
|
|
959
|
-
addInclusion(included, action, {
|
|
960
|
-
source: "CUSTOM_GOAL",
|
|
961
|
-
goalResourceName: customGoal.resourceName
|
|
962
|
-
});
|
|
963
|
-
}
|
|
964
|
-
}
|
|
965
|
-
}
|
|
966
|
-
return {
|
|
967
|
-
campaign: row.campaign,
|
|
968
|
-
config,
|
|
969
|
-
categoryGoalSource,
|
|
970
|
-
categoryOriginGoals,
|
|
971
|
-
customGoal,
|
|
972
|
-
conversionActions: [...included.values()],
|
|
973
|
-
...missingCustomGoalResourceName ? { missingCustomGoalResourceName } : {},
|
|
974
|
-
missingConversionActionResourceNames
|
|
975
|
-
};
|
|
976
|
-
});
|
|
977
|
-
}
|
|
978
|
-
|
|
979
895
|
// ../integration-google-ads/src/types.ts
|
|
980
896
|
var GoogleAdsApiError = class extends Error {
|
|
981
897
|
constructor(message, status, providerStatus, requestId, retryAfter) {
|
|
@@ -1576,8 +1492,7 @@ var GoogleAdsClient = class {
|
|
|
1576
1492
|
...raw,
|
|
1577
1493
|
// A result exactly at the cap may have more rows upstream. Treat it
|
|
1578
1494
|
// as incomplete rather than silently deriving absent campaign goals.
|
|
1579
|
-
campaignGoalsComplete: campaignGoals.data.length < GOOGLE_ADS_MAX_RESULT_ROWS
|
|
1580
|
-
effectiveCampaignGoalInputs: resolveEffectiveCampaignGoalInputs(raw)
|
|
1495
|
+
campaignGoalsComplete: campaignGoals.data.length < GOOGLE_ADS_MAX_RESULT_ROWS
|
|
1581
1496
|
},
|
|
1582
1497
|
metadata: {
|
|
1583
1498
|
apiVersion: GOOGLE_ADS_API_VERSION,
|
|
@@ -4237,7 +4152,7 @@ function parseTrackedQueryResponse(body, model) {
|
|
|
4237
4152
|
provider: "gemini",
|
|
4238
4153
|
rawResponse,
|
|
4239
4154
|
model,
|
|
4240
|
-
servedModel:
|
|
4155
|
+
servedModel: normalizeServedModel(rawResponse.modelVersion),
|
|
4241
4156
|
groundingSources: parsed.groundingSources,
|
|
4242
4157
|
searchQueries: parsed.searchQueries,
|
|
4243
4158
|
usage: extractUsageFromRaw(rawResponse),
|
|
@@ -4261,9 +4176,6 @@ function normalizeResult(raw) {
|
|
|
4261
4176
|
function hasParsedResponseContent(rawResponse) {
|
|
4262
4177
|
return Array.isArray(rawResponse.candidates) && rawResponse.candidates.length > 0;
|
|
4263
4178
|
}
|
|
4264
|
-
function extractServedModel(rawResponse) {
|
|
4265
|
-
return normalizeServedModel(rawResponse.modelVersion);
|
|
4266
|
-
}
|
|
4267
4179
|
function reparseStoredResult(rawResponse) {
|
|
4268
4180
|
const groundingSources = extractGroundingMetadataFromRaw(rawResponse);
|
|
4269
4181
|
const searchQueries = extractSearchQueriesFromRaw(rawResponse);
|
|
@@ -4447,49 +4359,25 @@ var DEFAULT_OUTPUT_DIMENSIONALITY = 768;
|
|
|
4447
4359
|
var CLUSTERING_TASK_TYPE = "CLUSTERING";
|
|
4448
4360
|
async function embedQueries(queries2, options) {
|
|
4449
4361
|
if (queries2.length === 0) return [];
|
|
4450
|
-
if (!options.apiKey
|
|
4451
|
-
|
|
4452
|
-
|
|
4453
|
-
const client = options.client ?? createGeminiEmbedClient(options.apiKey, options.baseUrl);
|
|
4454
|
-
return client.embedBatch(queries2, {
|
|
4362
|
+
if (!options.apiKey) throw new Error("embedQueries: missing apiKey");
|
|
4363
|
+
const genai = new GoogleGenAI2({ apiKey: options.apiKey, ...options.baseUrl ? { httpOptions: { baseUrl: options.baseUrl } } : {} });
|
|
4364
|
+
const response = await genai.models.embedContent({
|
|
4455
4365
|
model: options.model ?? DEFAULT_EMBED_MODEL,
|
|
4456
|
-
|
|
4457
|
-
outputDimensionality: options.outputDimensionality ?? DEFAULT_OUTPUT_DIMENSIONALITY
|
|
4366
|
+
contents: queries2,
|
|
4367
|
+
config: { taskType: CLUSTERING_TASK_TYPE, outputDimensionality: options.outputDimensionality ?? DEFAULT_OUTPUT_DIMENSIONALITY }
|
|
4458
4368
|
});
|
|
4369
|
+
return extractEmbeddingVectors(response, queries2.length);
|
|
4459
4370
|
}
|
|
4460
4371
|
function extractEmbeddingVectors(response, expectedLength) {
|
|
4461
4372
|
const embeddings = response?.embeddings ?? [];
|
|
4462
4373
|
if (embeddings.length !== expectedLength) {
|
|
4463
|
-
throw new Error(
|
|
4464
|
-
`embedQueries: expected ${expectedLength} embeddings, got ${embeddings.length}`
|
|
4465
|
-
);
|
|
4374
|
+
throw new Error(`embedQueries: expected ${expectedLength} embeddings, got ${embeddings.length}`);
|
|
4466
4375
|
}
|
|
4467
4376
|
return embeddings.map((e, i) => {
|
|
4468
|
-
if (!e.values || e.values.length === 0) {
|
|
4469
|
-
throw new Error(`embedQueries: missing values for query at index ${i}`);
|
|
4470
|
-
}
|
|
4377
|
+
if (!e.values || e.values.length === 0) throw new Error(`embedQueries: missing values for query at index ${i}`);
|
|
4471
4378
|
return e.values;
|
|
4472
4379
|
});
|
|
4473
4380
|
}
|
|
4474
|
-
function createEmbedGenAI(apiKey, baseUrl) {
|
|
4475
|
-
return new GoogleGenAI2({ apiKey, ...baseUrl ? { httpOptions: { baseUrl } } : {} });
|
|
4476
|
-
}
|
|
4477
|
-
function createGeminiEmbedClient(apiKey, baseUrl) {
|
|
4478
|
-
const genai = createEmbedGenAI(apiKey, baseUrl);
|
|
4479
|
-
return {
|
|
4480
|
-
async embedBatch(queries2, opts) {
|
|
4481
|
-
const response = await genai.models.embedContent({
|
|
4482
|
-
model: opts.model,
|
|
4483
|
-
contents: queries2,
|
|
4484
|
-
config: {
|
|
4485
|
-
taskType: opts.taskType,
|
|
4486
|
-
outputDimensionality: opts.outputDimensionality
|
|
4487
|
-
}
|
|
4488
|
-
});
|
|
4489
|
-
return extractEmbeddingVectors(response, queries2.length);
|
|
4490
|
-
}
|
|
4491
|
-
};
|
|
4492
|
-
}
|
|
4493
4381
|
|
|
4494
4382
|
// ../provider-gemini/src/list-models.ts
|
|
4495
4383
|
function listModels(config, signal) {
|
|
@@ -4727,7 +4615,7 @@ function buildTrackedQueryRequest2(input) {
|
|
|
4727
4615
|
// search-required-v1: web_search is the only tool, so requiring a tool
|
|
4728
4616
|
// call requires a search. See OPENAI_RETRIEVAL_CONTRACT.
|
|
4729
4617
|
tool_choice: "required",
|
|
4730
|
-
input:
|
|
4618
|
+
input: input.query
|
|
4731
4619
|
};
|
|
4732
4620
|
return { endpoint: OPENAI_RESPONSES_ENDPOINT, body };
|
|
4733
4621
|
}
|
|
@@ -4751,7 +4639,7 @@ function parseTrackedQueryResponse2(body, model) {
|
|
|
4751
4639
|
provider: "openai",
|
|
4752
4640
|
rawResponse,
|
|
4753
4641
|
model,
|
|
4754
|
-
servedModel:
|
|
4642
|
+
servedModel: normalizeServedModel(rawResponse.model),
|
|
4755
4643
|
groundingSources: parsed.groundingSources,
|
|
4756
4644
|
searchQueries: parsed.searchQueries,
|
|
4757
4645
|
retrievalStatus: parsed.retrievalStatus,
|
|
@@ -4778,9 +4666,6 @@ function normalizeResult2(raw) {
|
|
|
4778
4666
|
function hasParsedResponseContent2(rawResponse) {
|
|
4779
4667
|
return Array.isArray(rawResponse.output) && rawResponse.output.length > 0;
|
|
4780
4668
|
}
|
|
4781
|
-
function extractServedModel2(rawResponse) {
|
|
4782
|
-
return normalizeServedModel(rawResponse.model);
|
|
4783
|
-
}
|
|
4784
4669
|
function reparseStoredResult2(rawResponse) {
|
|
4785
4670
|
const groundingSources = extractGroundingSourcesFromRaw(rawResponse);
|
|
4786
4671
|
const searchQueries = extractSearchQueriesFromRaw2(rawResponse);
|
|
@@ -4805,9 +4690,6 @@ function extractRetrievalStatusFromRaw(rawResponse) {
|
|
|
4805
4690
|
}
|
|
4806
4691
|
return RetrievalStatuses["not-used"];
|
|
4807
4692
|
}
|
|
4808
|
-
function buildPrompt2(query) {
|
|
4809
|
-
return query;
|
|
4810
|
-
}
|
|
4811
4693
|
function extractResponseText(response) {
|
|
4812
4694
|
try {
|
|
4813
4695
|
const parts = [];
|
|
@@ -5235,7 +5117,7 @@ function parseTrackedQueryResponse3(body, model) {
|
|
|
5235
5117
|
provider: "claude",
|
|
5236
5118
|
rawResponse,
|
|
5237
5119
|
model,
|
|
5238
|
-
servedModel:
|
|
5120
|
+
servedModel: extractServedModel(rawResponse),
|
|
5239
5121
|
groundingSources: parsed.groundingSources,
|
|
5240
5122
|
searchQueries: parsed.searchQueries,
|
|
5241
5123
|
retrievalStatus: parsed.retrievalStatus,
|
|
@@ -5264,7 +5146,7 @@ function normalizeResult3(raw) {
|
|
|
5264
5146
|
function hasParsedResponseContent3(rawResponse) {
|
|
5265
5147
|
return Array.isArray(rawResponse.content) && rawResponse.content.length > 0;
|
|
5266
5148
|
}
|
|
5267
|
-
function
|
|
5149
|
+
function extractServedModel(rawResponse) {
|
|
5268
5150
|
return normalizeServedModel(rawResponse.model);
|
|
5269
5151
|
}
|
|
5270
5152
|
function reparseStoredResult3(rawResponse) {
|
|
@@ -5802,7 +5684,7 @@ function buildTrackedQueryRequest4(input) {
|
|
|
5802
5684
|
},
|
|
5803
5685
|
{
|
|
5804
5686
|
role: "user",
|
|
5805
|
-
content:
|
|
5687
|
+
content: buildPrompt2(input.query, input.location)
|
|
5806
5688
|
}
|
|
5807
5689
|
]
|
|
5808
5690
|
};
|
|
@@ -5830,7 +5712,7 @@ function parseTrackedQueryResponse4(body, model) {
|
|
|
5830
5712
|
provider: "local",
|
|
5831
5713
|
rawResponse,
|
|
5832
5714
|
model,
|
|
5833
|
-
servedModel:
|
|
5715
|
+
servedModel: normalizeServedModel(rawResponse.model),
|
|
5834
5716
|
groundingSources: [],
|
|
5835
5717
|
searchQueries: [],
|
|
5836
5718
|
usage: extractUsageFromRaw4(rawResponse),
|
|
@@ -5851,7 +5733,7 @@ function normalizeResult4(raw) {
|
|
|
5851
5733
|
searchQueries: raw.searchQueries
|
|
5852
5734
|
};
|
|
5853
5735
|
}
|
|
5854
|
-
function
|
|
5736
|
+
function buildPrompt2(query, location) {
|
|
5855
5737
|
const locationContext = location ? ` The user is searching from ${location.city}, ${location.region}, ${location.country}.` : "";
|
|
5856
5738
|
return `Based on your training knowledge, what websites, services, or organizations are commonly associated with "${query}"?${locationContext} List the most relevant ones and include their domain names (e.g. example.com) where you know them.`;
|
|
5857
5739
|
}
|
|
@@ -5878,9 +5760,6 @@ async function generateText4(prompt, config) {
|
|
|
5878
5760
|
);
|
|
5879
5761
|
return response.choices[0]?.message?.content ?? "";
|
|
5880
5762
|
}
|
|
5881
|
-
function extractServedModel4(rawResponse) {
|
|
5882
|
-
return normalizeServedModel(rawResponse.model);
|
|
5883
|
-
}
|
|
5884
5763
|
function extractUsageFromRaw4(rawResponse) {
|
|
5885
5764
|
const usage = rawResponse.usage;
|
|
5886
5765
|
if (usage === null || typeof usage !== "object") return void 0;
|
|
@@ -6723,7 +6602,7 @@ function parseTrackedQueryResponse5(body, model) {
|
|
|
6723
6602
|
provider: "perplexity",
|
|
6724
6603
|
rawResponse: body,
|
|
6725
6604
|
model: resolveModel3(model),
|
|
6726
|
-
servedModel:
|
|
6605
|
+
servedModel: normalizeServedModel(body.model),
|
|
6727
6606
|
groundingSources: parsed.groundingSources,
|
|
6728
6607
|
searchQueries: parsed.searchQueries,
|
|
6729
6608
|
retrievalStatus: parsed.retrievalStatus,
|
|
@@ -6756,9 +6635,6 @@ function hasParsedResponseContent4(rawResponse) {
|
|
|
6756
6635
|
if (!nestedResponse) return false;
|
|
6757
6636
|
return Array.isArray(nestedResponse.choices) && nestedResponse.choices.length > 0 || Array.isArray(nestedResponse.search_results) && nestedResponse.search_results.length > 0 || Array.isArray(nestedResponse.citations) && nestedResponse.citations.length > 0;
|
|
6758
6637
|
}
|
|
6759
|
-
function extractServedModel5(rawResponse) {
|
|
6760
|
-
return normalizeServedModel(rawResponse.model);
|
|
6761
|
-
}
|
|
6762
6638
|
function reparseStoredResult4(rawResponse) {
|
|
6763
6639
|
const agent = agentResponseOf(rawResponse);
|
|
6764
6640
|
if (agent) return parseAgentResponse(agent);
|
|
@@ -7197,7 +7073,7 @@ async function executeTrackedQuery6(input) {
|
|
|
7197
7073
|
provider: "muse",
|
|
7198
7074
|
rawResponse,
|
|
7199
7075
|
model,
|
|
7200
|
-
servedModel:
|
|
7076
|
+
servedModel: normalizeServedModel(rawResponse.model),
|
|
7201
7077
|
groundingSources: parsed.groundingSources,
|
|
7202
7078
|
searchQueries: parsed.searchQueries,
|
|
7203
7079
|
retrievalStatus: parsed.retrievalStatus,
|
|
@@ -7208,9 +7084,6 @@ async function executeTrackedQuery6(input) {
|
|
|
7208
7084
|
throw new Error(`[provider-muse] ${describeError(err)}`);
|
|
7209
7085
|
}
|
|
7210
7086
|
}
|
|
7211
|
-
function extractServedModel6(rawResponse) {
|
|
7212
|
-
return normalizeServedModel(rawResponse.model);
|
|
7213
|
-
}
|
|
7214
7087
|
function extractUsage(rawResponse) {
|
|
7215
7088
|
const usage = asRecord(rawResponse.usage);
|
|
7216
7089
|
if (!usage) return void 0;
|
|
@@ -7422,7 +7295,7 @@ var museAdapter = {
|
|
|
7422
7295
|
|
|
7423
7296
|
// src/embed.ts
|
|
7424
7297
|
var DEFAULT_EMBED_PROJECT_TABS = ["overview"];
|
|
7425
|
-
var SERVER_ENFORCED_EMBED_PROJECT_TABS = ["overview", "technical-aeo"
|
|
7298
|
+
var SERVER_ENFORCED_EMBED_PROJECT_TABS = ["overview", "technical-aeo"];
|
|
7426
7299
|
function unsupportedEmbedProjectTabs(projectTabs) {
|
|
7427
7300
|
if (!projectTabs) return [];
|
|
7428
7301
|
const supported = new Set(SERVER_ENFORCED_EMBED_PROJECT_TABS);
|
|
@@ -7437,6 +7310,8 @@ function resolveEmbedConfig(env, config) {
|
|
|
7437
7310
|
const views = normalizeIdTokens(rawViews);
|
|
7438
7311
|
const rawProjectTabs = env.CANONRY_EMBED_PROJECT_TABS !== void 0 ? splitList(env.CANONRY_EMBED_PROJECT_TABS) : splitList(embed?.projectTabs);
|
|
7439
7312
|
const projectTabs = normalizeIdTokens(rawProjectTabs) ?? (enabled ? DEFAULT_EMBED_PROJECT_TABS : void 0);
|
|
7313
|
+
const projectTabsError = enabled ? embedProjectTabsError(projectTabs) : void 0;
|
|
7314
|
+
if (projectTabsError) throw new Error(projectTabsError);
|
|
7440
7315
|
return {
|
|
7441
7316
|
enabled,
|
|
7442
7317
|
allowedOrigins,
|
|
@@ -7976,13 +7851,38 @@ function fitToByteBudget(payload) {
|
|
|
7976
7851
|
return JSON.stringify(current);
|
|
7977
7852
|
}
|
|
7978
7853
|
|
|
7854
|
+
// src/ui-telemetry-gate.ts
|
|
7855
|
+
var UI_EVENT_MINUTE_CAPACITY = 60;
|
|
7856
|
+
var UI_EVENT_HOUR_CAPACITY = 600;
|
|
7857
|
+
function createUiTelemetryGate(options = {}) {
|
|
7858
|
+
const now = options.now ?? Date.now;
|
|
7859
|
+
const enabled = options.enabled ?? isTelemetryEnabled;
|
|
7860
|
+
const record2 = options.record ?? recordDashboardEvent;
|
|
7861
|
+
const buckets = [
|
|
7862
|
+
{ capacity: UI_EVENT_MINUTE_CAPACITY, perMs: UI_EVENT_MINUTE_CAPACITY / 6e4, tokens: UI_EVENT_MINUTE_CAPACITY },
|
|
7863
|
+
{ capacity: UI_EVENT_HOUR_CAPACITY, perMs: UI_EVENT_HOUR_CAPACITY / 36e5, tokens: UI_EVENT_HOUR_CAPACITY }
|
|
7864
|
+
];
|
|
7865
|
+
let refilledAt = now();
|
|
7866
|
+
return (event) => {
|
|
7867
|
+
if (!enabled()) return false;
|
|
7868
|
+
const at = now();
|
|
7869
|
+
const elapsed = Math.max(0, at - refilledAt);
|
|
7870
|
+
refilledAt = at;
|
|
7871
|
+
for (const bucket of buckets) bucket.tokens = Math.min(bucket.capacity, bucket.tokens + elapsed * bucket.perMs);
|
|
7872
|
+
if (buckets.some((bucket) => bucket.tokens < 1)) return false;
|
|
7873
|
+
for (const bucket of buckets) bucket.tokens -= 1;
|
|
7874
|
+
record2(event);
|
|
7875
|
+
return true;
|
|
7876
|
+
};
|
|
7877
|
+
}
|
|
7878
|
+
|
|
7979
7879
|
// src/instance-identity.ts
|
|
7980
7880
|
function nonBlank(value) {
|
|
7981
7881
|
const trimmed = value?.trim();
|
|
7982
7882
|
return trimmed ? trimmed : void 0;
|
|
7983
7883
|
}
|
|
7984
7884
|
function resolveBuildCommit(env = process.env) {
|
|
7985
|
-
const embedded = true ? "
|
|
7885
|
+
const embedded = true ? "9ddd0d5e4575e0983aae488bd457b664c8b9fd4a" : void 0;
|
|
7986
7886
|
return nonBlank(embedded) ?? nonBlank(env.CANONRY_COMMIT);
|
|
7987
7887
|
}
|
|
7988
7888
|
function resolveInstanceIdentity(env = process.env) {
|
|
@@ -12949,18 +12849,17 @@ function withAttemptTimeout(promise, timeoutMs, label) {
|
|
|
12949
12849
|
);
|
|
12950
12850
|
});
|
|
12951
12851
|
}
|
|
12952
|
-
async function embedWithRetry(fn
|
|
12953
|
-
const attemptTimeoutMs =
|
|
12852
|
+
async function embedWithRetry(fn) {
|
|
12853
|
+
const attemptTimeoutMs = EMBED_ATTEMPT_TIMEOUT_MS;
|
|
12954
12854
|
return withRetry(
|
|
12955
12855
|
() => withAttemptTimeout(fn(), attemptTimeoutMs, "Discovery embedding call"),
|
|
12956
12856
|
{
|
|
12957
|
-
maxRetries:
|
|
12857
|
+
maxRetries: EMBED_RETRY_MAX_RETRIES,
|
|
12958
12858
|
isRetryable: isRetryableHttpError,
|
|
12959
12859
|
maxDelayMs: EMBED_RETRY_MAX_DELAY_MS,
|
|
12960
|
-
|
|
12961
|
-
onRetry: opts.onRetry ?? (({ attempt, delayMs }) => {
|
|
12860
|
+
onRetry: ({ attempt, delayMs }) => {
|
|
12962
12861
|
log13.warn("discovery.embed.retry", { attempt, delayMs });
|
|
12963
|
-
}
|
|
12862
|
+
}
|
|
12964
12863
|
}
|
|
12965
12864
|
);
|
|
12966
12865
|
}
|
|
@@ -12975,7 +12874,7 @@ async function executeDiscoveryRun(opts) {
|
|
|
12975
12874
|
const canonicalDomains = effectiveDomains({
|
|
12976
12875
|
canonicalDomain: projectRow.canonicalDomain,
|
|
12977
12876
|
ownedDomains: projectRow.ownedDomains
|
|
12978
|
-
});
|
|
12877
|
+
}).map(normalizeProjectDomain);
|
|
12979
12878
|
const brandNames = effectiveBrandNames({
|
|
12980
12879
|
displayName: projectRow.displayName,
|
|
12981
12880
|
aliases: projectRow.aliases
|
|
@@ -12987,7 +12886,7 @@ async function executeDiscoveryRun(opts) {
|
|
|
12987
12886
|
canonicalDomains,
|
|
12988
12887
|
competitorDomains: projectCompetitors
|
|
12989
12888
|
};
|
|
12990
|
-
const deps =
|
|
12889
|
+
const deps = buildDefaultDeps(opts.registry);
|
|
12991
12890
|
const result2 = await executeDiscovery({
|
|
12992
12891
|
db: opts.db,
|
|
12993
12892
|
runId: opts.runId,
|
|
@@ -13049,8 +12948,8 @@ function buildDefaultDeps(registry) {
|
|
|
13049
12948
|
async seed(input) {
|
|
13050
12949
|
const prompt = buildSeedPrompt(input);
|
|
13051
12950
|
const providerNames = input.seedProviders && input.seedProviders.length > 0 ? [...input.seedProviders] : ["gemini"];
|
|
13052
|
-
const
|
|
13053
|
-
|
|
12951
|
+
const admittedProviders = providerNames.map((name) => ({ name, seedProvider: seedProviderFor(name) }));
|
|
12952
|
+
const perProvider = await Promise.all(admittedProviders.map(async ({ name, seedProvider }) => {
|
|
13054
12953
|
const raw = await seedProvider.adapter.executeTrackedQuery(
|
|
13055
12954
|
{
|
|
13056
12955
|
query: prompt,
|
|
@@ -14795,7 +14694,7 @@ function readStoredGroundingSources(rawResponse) {
|
|
|
14795
14694
|
return result2;
|
|
14796
14695
|
}
|
|
14797
14696
|
async function backfillInsightsCommand(project, opts) {
|
|
14798
|
-
const { IntelligenceService: IntelligenceService2 } = await import("./intelligence-service-
|
|
14697
|
+
const { IntelligenceService: IntelligenceService2 } = await import("./intelligence-service-YCMRTVCI.js");
|
|
14799
14698
|
const config = loadConfig();
|
|
14800
14699
|
const db = createClient(config.database);
|
|
14801
14700
|
migrate(db);
|
|
@@ -16554,8 +16453,9 @@ var Notifier = class {
|
|
|
16554
16453
|
})),
|
|
16555
16454
|
dashboardUrl: `${this.serverUrl}/projects/${project.name}`
|
|
16556
16455
|
};
|
|
16557
|
-
await this.sendWebhook(config.url, payload, notif.id, projectId, notif.webhookSecret ?? null)
|
|
16558
|
-
|
|
16456
|
+
if (await this.sendWebhook(config.url, payload, notif.id, projectId, notif.webhookSecret ?? null)) {
|
|
16457
|
+
for (const insight of relevantInsights) this.rememberInsightNotified(projectId, insight);
|
|
16458
|
+
}
|
|
16559
16459
|
}
|
|
16560
16460
|
}
|
|
16561
16461
|
}
|
|
@@ -16725,7 +16625,8 @@ var Notifier = class {
|
|
|
16725
16625
|
const groupSiblings = this.db.select().from(runs).where(and18(
|
|
16726
16626
|
eq20(runs.projectId, projectId),
|
|
16727
16627
|
eq20(runs.kind, thisRun.kind),
|
|
16728
|
-
eq20(runs.createdAt, thisRun.createdAt)
|
|
16628
|
+
eq20(runs.createdAt, thisRun.createdAt),
|
|
16629
|
+
notProbeRun()
|
|
16729
16630
|
)).all();
|
|
16730
16631
|
const stillPending = groupSiblings.some((r) => r.status === "queued" || r.status === "running");
|
|
16731
16632
|
if (stillPending) return [];
|
|
@@ -16751,7 +16652,8 @@ var Notifier = class {
|
|
|
16751
16652
|
and18(
|
|
16752
16653
|
eq20(runs.projectId, projectId),
|
|
16753
16654
|
eq20(runs.kind, thisRun.kind),
|
|
16754
|
-
or(eq20(runs.status, "completed"), eq20(runs.status, "partial"))
|
|
16655
|
+
or(eq20(runs.status, "completed"), eq20(runs.status, "partial")),
|
|
16656
|
+
notProbeRun()
|
|
16755
16657
|
)
|
|
16756
16658
|
).orderBy(desc9(runs.createdAt), desc9(runs.id)).limit(RECENT_FETCH_LIMIT).all();
|
|
16757
16659
|
const groups = groupRunsByCreatedAt(recentRuns);
|
|
@@ -19236,11 +19138,12 @@ function truncateToByteLimit(text, maxBytes) {
|
|
|
19236
19138
|
if (Buffer.byteLength(text, "utf8") <= maxBytes) return text;
|
|
19237
19139
|
const suffix = "\u2026[truncated]";
|
|
19238
19140
|
const budget = maxBytes - Buffer.byteLength(suffix, "utf8");
|
|
19239
|
-
|
|
19240
|
-
|
|
19241
|
-
|
|
19141
|
+
const buf = Buffer.from(text, "utf8");
|
|
19142
|
+
let end = budget;
|
|
19143
|
+
while (end > 0 && (buf[end] & 192) === 128) {
|
|
19144
|
+
end -= 1;
|
|
19242
19145
|
}
|
|
19243
|
-
return buf.toString("utf8") + suffix;
|
|
19146
|
+
return buf.subarray(0, end).toString("utf8") + suffix;
|
|
19244
19147
|
}
|
|
19245
19148
|
async function runSummaryLlm(args) {
|
|
19246
19149
|
const context = {
|
|
@@ -19261,8 +19164,7 @@ async function compactMessages(args) {
|
|
|
19261
19164
|
if (split === 0) return null;
|
|
19262
19165
|
const chunk = messages.slice(0, split);
|
|
19263
19166
|
const suffix = messages.slice(split);
|
|
19264
|
-
const
|
|
19265
|
-
const rawSummary = await summarize({ model: args.model, chunk, getApiKey: args.getApiKey });
|
|
19167
|
+
const rawSummary = await runSummaryLlm({ model: args.model, chunk, getApiKey: args.getApiKey });
|
|
19266
19168
|
const summary = truncateToByteLimit(rawSummary, AGENT_MEMORY_VALUE_MAX_BYTES);
|
|
19267
19169
|
writeCompactionNote(args.db, {
|
|
19268
19170
|
projectId: args.projectId,
|
|
@@ -22197,6 +22099,7 @@ function createGoogleMarketingConfigCredentialStore(input) {
|
|
|
22197
22099
|
};
|
|
22198
22100
|
}
|
|
22199
22101
|
async function createServer(opts) {
|
|
22102
|
+
const embed = resolveEmbedConfig(process.env, opts.config);
|
|
22200
22103
|
const operatorApiKeyIds = resolveOperatorApiKeyIds(process.env);
|
|
22201
22104
|
const dashboardManagedRunKinds = resolveDashboardManagedRunKinds(process.env, opts.config);
|
|
22202
22105
|
const operationalLogs = new OperationalLogStore(opts.db, {
|
|
@@ -23025,7 +22928,6 @@ async function createServer(opts) {
|
|
|
23025
22928
|
const rawBasePath = process.env.CANONRY_BASE_PATH ?? opts.config.basePath;
|
|
23026
22929
|
const normalizedBasePath = rawBasePath ? "/" + rawBasePath.replace(/^\//, "").replace(/\/?$/, "/") : void 0;
|
|
23027
22930
|
const basePath = normalizedBasePath === "/" ? void 0 : normalizedBasePath;
|
|
23028
|
-
const embed = resolveEmbedConfig(process.env, opts.config);
|
|
23029
22931
|
const embedCsp = embed.enabled ? frameAncestorsHeaderValue(embed.allowedOrigins) : void 0;
|
|
23030
22932
|
const unsupportedProjectTabs = unsupportedEmbedProjectTabs(embed.projectTabs);
|
|
23031
22933
|
if (embed.enabled && unsupportedProjectTabs.length > 0) {
|
|
@@ -23209,14 +23111,19 @@ async function createServer(opts) {
|
|
|
23209
23111
|
password,
|
|
23210
23112
|
opts.config.dashboardPasswordHash
|
|
23211
23113
|
);
|
|
23212
|
-
|
|
23114
|
+
const onDisk = verification.ok && verification.needsRehash ? loadConfigRaw() : null;
|
|
23115
|
+
if (!verification.ok || onDisk && onDisk.dashboardPasswordHash !== opts.config.dashboardPasswordHash) {
|
|
23213
23116
|
return reply.status(401).send({
|
|
23214
23117
|
error: { code: "AUTH_INVALID", message: "Incorrect password" }
|
|
23215
23118
|
});
|
|
23216
23119
|
}
|
|
23217
23120
|
if (verification.needsRehash) {
|
|
23218
|
-
|
|
23219
|
-
|
|
23121
|
+
if (fs9.existsSync(getConfigPath()) && (!onDisk || typeof onDisk !== "object" || Array.isArray(onDisk) || !onDisk.apiUrl || !onDisk.database || !onDisk.apiKey)) {
|
|
23122
|
+
throw new Error("Cannot migrate dashboard password: config.yaml is unreadable or invalid");
|
|
23123
|
+
}
|
|
23124
|
+
const migratedHash = hashDashboardPassword(password);
|
|
23125
|
+
saveConfig({ ...onDisk ?? opts.config, dashboardPasswordHash: migratedHash });
|
|
23126
|
+
opts.config.dashboardPasswordHash = migratedHash;
|
|
23220
23127
|
}
|
|
23221
23128
|
if (!createPasswordSession(reply)) {
|
|
23222
23129
|
return reply.status(401).send({
|
|
@@ -23899,10 +23806,10 @@ async function createServer(opts) {
|
|
|
23899
23806
|
void setTelemetryPreference(enabled, "api");
|
|
23900
23807
|
opts.config.telemetry = enabled;
|
|
23901
23808
|
},
|
|
23902
|
-
recordOnboardingEvent: (event) =>
|
|
23903
|
-
|
|
23904
|
-
|
|
23905
|
-
|
|
23809
|
+
recordOnboardingEvent: (event) => recordDashboardEvent(event),
|
|
23810
|
+
// Answers false while telemetry is off or the per-process cap is spent, so
|
|
23811
|
+
// the dashboard stops sending for the session.
|
|
23812
|
+
recordUiEvent: createUiTelemetryGate(),
|
|
23906
23813
|
submitFeedback: (submission, context) => sendFeedback(submission, context),
|
|
23907
23814
|
onCdpConfigure: async (host, port2) => {
|
|
23908
23815
|
if (!opts.config.cdp) opts.config.cdp = {};
|
|
@@ -24017,6 +23924,8 @@ async function createServer(opts) {
|
|
|
24017
23924
|
}
|
|
24018
23925
|
if (embed.enabled) {
|
|
24019
23926
|
const embedClient = embedClientConfigForRequest(embed, projectTabsOverride, themeOverride, renderTokenOverride);
|
|
23927
|
+
const projectTabsError = embedProjectTabsError(embedClient?.projectTabs);
|
|
23928
|
+
if (projectTabsError) throw validationError(projectTabsError);
|
|
24020
23929
|
if (embedClient) clientConfig.embed = embedClient;
|
|
24021
23930
|
}
|
|
24022
23931
|
const configScript = `<script>window.__CANONRY_CONFIG__=${serializeForInlineScript(clientConfig)}</script>`;
|