@ainyc/canonry 4.87.0 → 4.89.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/agent-workspace/skills/canonry/references/canonry-cli.md +16 -0
- package/assets/agent-workspace/skills/canonry/references/server-side-traffic.md +19 -0
- package/assets/assets/{BacklinksPage-BPvsw_Bi.js → BacklinksPage-Cl3V55iK.js} +1 -1
- package/assets/assets/{ChartPrimitives-BdlKCq7y.js → ChartPrimitives-D4D_lSIp.js} +1 -1
- package/assets/assets/{ProjectPage-1Q8YC9Vd.js → ProjectPage-Dwwcddk2.js} +1 -1
- package/assets/assets/{RunRow-DcSsnE5c.js → RunRow-CNjwUkqj.js} +1 -1
- package/assets/assets/{RunsPage-DKoIMkQL.js → RunsPage-owFYxiRU.js} +1 -1
- package/assets/assets/{SettingsPage-bH3PdNKb.js → SettingsPage-D3rc2Hze.js} +1 -1
- package/assets/assets/{TrafficPage-IW_DX-0V.js → TrafficPage-BDkhe0Iz.js} +1 -1
- package/assets/assets/TrafficSourceDetailPage-CUw6Odt1.js +1 -0
- package/assets/assets/{arrow-left-B5Du72nk.js → arrow-left-BAOMqvGW.js} +1 -1
- package/assets/assets/{extract-error-message-C7Vhd5zH.js → extract-error-message-BO0DeR7V.js} +1 -1
- package/assets/assets/{index-C_ZzKZfM.js → index-BbnglhBg.js} +79 -79
- package/assets/assets/index-fLUYE9Z5.css +1 -0
- package/assets/assets/{trash-2-DWcofmpv.js → trash-2-RQK6oqQJ.js} +1 -1
- package/assets/index.html +2 -2
- package/dist/{chunk-MDRDX5R2.js → chunk-LRO4CLPL.js} +230 -1
- package/dist/{chunk-DUDFNP5Y.js → chunk-MUPIPQBB.js} +50 -7
- package/dist/{chunk-6XMXBAEW.js → chunk-PRKBJNAG.js} +1 -1
- package/dist/{chunk-5LW7CJAO.js → chunk-WEV4RH25.js} +30 -6
- package/dist/cli.js +44 -14
- package/dist/index.d.ts +9 -1
- package/dist/index.js +4 -4
- package/dist/{intelligence-service-XUKYOHKL.js → intelligence-service-SO46DMGR.js} +2 -2
- package/dist/mcp.js +2 -2
- package/package.json +8 -8
- package/assets/assets/TrafficSourceDetailPage-DRHOGn9B.js +0 -1
- package/assets/assets/index-ClkRAeHL.css +0 -1
|
@@ -4555,6 +4555,20 @@ function coerceSkillManifest(parsed) {
|
|
|
4555
4555
|
|
|
4556
4556
|
// ../contracts/src/traffic.ts
|
|
4557
4557
|
import { z as z30 } from "zod";
|
|
4558
|
+
var trafficCrawlerSegmentsSchema = z30.object({
|
|
4559
|
+
content: z30.number().int().nonnegative(),
|
|
4560
|
+
sitemap: z30.number().int().nonnegative(),
|
|
4561
|
+
robots: z30.number().int().nonnegative(),
|
|
4562
|
+
asset: z30.number().int().nonnegative(),
|
|
4563
|
+
other: z30.number().int().nonnegative()
|
|
4564
|
+
});
|
|
4565
|
+
var trafficPathClassSchema = z30.enum([
|
|
4566
|
+
"content",
|
|
4567
|
+
"sitemap",
|
|
4568
|
+
"robots",
|
|
4569
|
+
"asset",
|
|
4570
|
+
"other"
|
|
4571
|
+
]);
|
|
4558
4572
|
var trafficSourceTypeSchema = z30.enum([
|
|
4559
4573
|
"cloud-run",
|
|
4560
4574
|
"wordpress",
|
|
@@ -4711,7 +4725,18 @@ var trafficBackfillResponseSchema = z30.object({
|
|
|
4711
4725
|
daysApplied: z30.number().int().positive()
|
|
4712
4726
|
});
|
|
4713
4727
|
var trafficSourceTotalsSchema = z30.object({
|
|
4728
|
+
/**
|
|
4729
|
+
* Total classified-crawler hits in the window. UNCHANGED contract — still the
|
|
4730
|
+
* full count across every path class. Use `crawlerContentHits` for the
|
|
4731
|
+
* "content was actually crawled" signal.
|
|
4732
|
+
*/
|
|
4714
4733
|
crawlerHits: z30.number().int().nonnegative(),
|
|
4734
|
+
/** Crawler hits against content/document paths only (= `crawlerSegments.content`). */
|
|
4735
|
+
crawlerContentHits: z30.number().int().nonnegative(),
|
|
4736
|
+
/** Infrastructure crawler hits — sitemap + robots + asset fetches (`crawlerSegments.{sitemap,robots,asset}`). */
|
|
4737
|
+
crawlerInfraHits: z30.number().int().nonnegative(),
|
|
4738
|
+
/** Full per-class crawler-hit breakdown; the five buckets sum to `crawlerHits`. */
|
|
4739
|
+
crawlerSegments: trafficCrawlerSegmentsSchema,
|
|
4715
4740
|
aiUserFetchHits: z30.number().int().nonnegative(),
|
|
4716
4741
|
aiReferralHits: z30.number().int().nonnegative(),
|
|
4717
4742
|
sampleCount: z30.number().int().nonnegative()
|
|
@@ -4742,6 +4767,8 @@ var trafficCrawlerEventEntrySchema = z30.object({
|
|
|
4742
4767
|
operator: z30.string(),
|
|
4743
4768
|
verificationStatus: z30.string(),
|
|
4744
4769
|
pathNormalized: z30.string(),
|
|
4770
|
+
/** Coarse class of the fetched path — lets the UI split content crawls from sitemap/robots/asset polling. */
|
|
4771
|
+
pathClass: trafficPathClassSchema,
|
|
4745
4772
|
status: z30.number().int(),
|
|
4746
4773
|
hits: z30.number().int().nonnegative()
|
|
4747
4774
|
});
|
|
@@ -4777,13 +4804,151 @@ var trafficEventsResponseSchema = z30.object({
|
|
|
4777
4804
|
windowStart: z30.string(),
|
|
4778
4805
|
windowEnd: z30.string(),
|
|
4779
4806
|
totals: z30.object({
|
|
4807
|
+
/** Total classified-crawler hits across the window. UNCHANGED contract. */
|
|
4780
4808
|
crawlerHits: z30.number().int().nonnegative(),
|
|
4809
|
+
/** Crawler hits against content/document paths only (= `crawlerSegments.content`). */
|
|
4810
|
+
crawlerContentHits: z30.number().int().nonnegative(),
|
|
4811
|
+
/** Infrastructure crawler hits — sitemap + robots + asset fetches. */
|
|
4812
|
+
crawlerInfraHits: z30.number().int().nonnegative(),
|
|
4813
|
+
/** Full per-class crawler-hit breakdown; the five buckets sum to `crawlerHits`. */
|
|
4814
|
+
crawlerSegments: trafficCrawlerSegmentsSchema,
|
|
4781
4815
|
aiUserFetchHits: z30.number().int().nonnegative(),
|
|
4782
4816
|
aiReferralHits: z30.number().int().nonnegative()
|
|
4783
4817
|
}),
|
|
4784
4818
|
events: z30.array(trafficEventEntrySchema)
|
|
4785
4819
|
});
|
|
4786
4820
|
|
|
4821
|
+
// ../contracts/src/traffic-path.ts
|
|
4822
|
+
var TrafficPathClasses = {
|
|
4823
|
+
content: "content",
|
|
4824
|
+
sitemap: "sitemap",
|
|
4825
|
+
robots: "robots",
|
|
4826
|
+
asset: "asset",
|
|
4827
|
+
other: "other"
|
|
4828
|
+
};
|
|
4829
|
+
var ROBOTS_BASENAMES = /* @__PURE__ */ new Set(["robots.txt", "llms.txt", "llms-full.txt"]);
|
|
4830
|
+
var ASSET_EXTENSIONS = /* @__PURE__ */ new Set([
|
|
4831
|
+
"css",
|
|
4832
|
+
"js",
|
|
4833
|
+
"mjs",
|
|
4834
|
+
"cjs",
|
|
4835
|
+
"map",
|
|
4836
|
+
"json",
|
|
4837
|
+
"png",
|
|
4838
|
+
"jpg",
|
|
4839
|
+
"jpeg",
|
|
4840
|
+
"webp",
|
|
4841
|
+
"avif",
|
|
4842
|
+
"gif",
|
|
4843
|
+
"svg",
|
|
4844
|
+
"ico",
|
|
4845
|
+
"bmp",
|
|
4846
|
+
"tif",
|
|
4847
|
+
"tiff",
|
|
4848
|
+
"woff",
|
|
4849
|
+
"woff2",
|
|
4850
|
+
"ttf",
|
|
4851
|
+
"otf",
|
|
4852
|
+
"eot",
|
|
4853
|
+
"mp4",
|
|
4854
|
+
"webm",
|
|
4855
|
+
"mov",
|
|
4856
|
+
"m4v",
|
|
4857
|
+
"mp3",
|
|
4858
|
+
"wav",
|
|
4859
|
+
"ogg",
|
|
4860
|
+
"flac",
|
|
4861
|
+
"m4a",
|
|
4862
|
+
"wasm"
|
|
4863
|
+
]);
|
|
4864
|
+
var DOCUMENT_EXTENSIONS = /* @__PURE__ */ new Set([
|
|
4865
|
+
"html",
|
|
4866
|
+
"htm",
|
|
4867
|
+
"xhtml",
|
|
4868
|
+
"shtml",
|
|
4869
|
+
"php",
|
|
4870
|
+
"php5",
|
|
4871
|
+
"php7",
|
|
4872
|
+
"asp",
|
|
4873
|
+
"aspx",
|
|
4874
|
+
"jsp",
|
|
4875
|
+
"jspx",
|
|
4876
|
+
"cfm",
|
|
4877
|
+
"md"
|
|
4878
|
+
]);
|
|
4879
|
+
var DOWNLOAD_EXTENSIONS = /* @__PURE__ */ new Set([
|
|
4880
|
+
"pdf",
|
|
4881
|
+
"csv",
|
|
4882
|
+
"tsv",
|
|
4883
|
+
"txt",
|
|
4884
|
+
"doc",
|
|
4885
|
+
"docx",
|
|
4886
|
+
"xls",
|
|
4887
|
+
"xlsx",
|
|
4888
|
+
"ppt",
|
|
4889
|
+
"pptx",
|
|
4890
|
+
"odt",
|
|
4891
|
+
"ods",
|
|
4892
|
+
"odp",
|
|
4893
|
+
"rtf",
|
|
4894
|
+
"zip",
|
|
4895
|
+
"gz",
|
|
4896
|
+
"tgz",
|
|
4897
|
+
"tar",
|
|
4898
|
+
"rar",
|
|
4899
|
+
"7z",
|
|
4900
|
+
"bz2",
|
|
4901
|
+
"xz",
|
|
4902
|
+
"rss",
|
|
4903
|
+
"atom",
|
|
4904
|
+
"ics",
|
|
4905
|
+
"vcf",
|
|
4906
|
+
"epub",
|
|
4907
|
+
"mobi",
|
|
4908
|
+
"apk",
|
|
4909
|
+
"dmg",
|
|
4910
|
+
"exe",
|
|
4911
|
+
"bin",
|
|
4912
|
+
"iso",
|
|
4913
|
+
"sql"
|
|
4914
|
+
]);
|
|
4915
|
+
var SITEMAP_BASENAME = /^sitemap(?:[-_]index)?$/;
|
|
4916
|
+
function classifyTrafficPath(pathNormalized) {
|
|
4917
|
+
const raw = (pathNormalized ?? "").trim();
|
|
4918
|
+
if (!raw) return TrafficPathClasses.other;
|
|
4919
|
+
const rawPath = raw.split(/[?#]/)[0] ?? "";
|
|
4920
|
+
const pathOnly = rawPath.length > 1 ? rawPath.replace(/\/+$/, "") || "/" : rawPath;
|
|
4921
|
+
if (!pathOnly) return TrafficPathClasses.other;
|
|
4922
|
+
const lower = pathOnly.toLowerCase();
|
|
4923
|
+
const segments = lower.split("/");
|
|
4924
|
+
const basename = segments[segments.length - 1] ?? "";
|
|
4925
|
+
if (ROBOTS_BASENAMES.has(basename)) return TrafficPathClasses.robots;
|
|
4926
|
+
if (lower.endsWith(".xml") || lower.endsWith(".xml.gz")) return TrafficPathClasses.sitemap;
|
|
4927
|
+
if (SITEMAP_BASENAME.test(basename)) return TrafficPathClasses.sitemap;
|
|
4928
|
+
const dot = basename.lastIndexOf(".");
|
|
4929
|
+
const ext = dot > 0 ? basename.slice(dot + 1) : "";
|
|
4930
|
+
if (ext) {
|
|
4931
|
+
if (ASSET_EXTENSIONS.has(ext)) return TrafficPathClasses.asset;
|
|
4932
|
+
if (DOCUMENT_EXTENSIONS.has(ext)) return TrafficPathClasses.content;
|
|
4933
|
+
if (DOWNLOAD_EXTENSIONS.has(ext)) return TrafficPathClasses.other;
|
|
4934
|
+
return TrafficPathClasses.content;
|
|
4935
|
+
}
|
|
4936
|
+
return TrafficPathClasses.content;
|
|
4937
|
+
}
|
|
4938
|
+
function emptyCrawlerSegments() {
|
|
4939
|
+
return { content: 0, sitemap: 0, robots: 0, asset: 0, other: 0 };
|
|
4940
|
+
}
|
|
4941
|
+
function segmentCrawlerHits(rows) {
|
|
4942
|
+
const segments = emptyCrawlerSegments();
|
|
4943
|
+
for (const row of rows) {
|
|
4944
|
+
segments[classifyTrafficPath(row.pathNormalized)] += row.hits;
|
|
4945
|
+
}
|
|
4946
|
+
return segments;
|
|
4947
|
+
}
|
|
4948
|
+
function sumInfraHits(segments) {
|
|
4949
|
+
return segments.sitemap + segments.robots + segments.asset;
|
|
4950
|
+
}
|
|
4951
|
+
|
|
4787
4952
|
// ../contracts/src/formatting.ts
|
|
4788
4953
|
function formatRatio(value) {
|
|
4789
4954
|
if (!Number.isFinite(value) || value === 0) return "0%";
|
|
@@ -5018,6 +5183,63 @@ function escapeLikePattern(value) {
|
|
|
5018
5183
|
return value.replace(/[\\%_]/g, (match) => `\\${match}`);
|
|
5019
5184
|
}
|
|
5020
5185
|
|
|
5186
|
+
// ../contracts/src/embed.ts
|
|
5187
|
+
var SELF_TOKEN = "'self'";
|
|
5188
|
+
function normalizeFrameOrigin(raw) {
|
|
5189
|
+
const trimmed = raw.trim();
|
|
5190
|
+
if (!trimmed) return null;
|
|
5191
|
+
if (trimmed === SELF_TOKEN) return SELF_TOKEN;
|
|
5192
|
+
if (trimmed.includes("*")) return null;
|
|
5193
|
+
let url;
|
|
5194
|
+
try {
|
|
5195
|
+
url = new URL(trimmed);
|
|
5196
|
+
} catch {
|
|
5197
|
+
return null;
|
|
5198
|
+
}
|
|
5199
|
+
if (url.protocol !== "http:" && url.protocol !== "https:") return null;
|
|
5200
|
+
if (url.username || url.password) return null;
|
|
5201
|
+
if (url.pathname && url.pathname !== "/" || url.search || url.hash) return null;
|
|
5202
|
+
if (!url.hostname) return null;
|
|
5203
|
+
return url.origin;
|
|
5204
|
+
}
|
|
5205
|
+
function splitList(raw) {
|
|
5206
|
+
if (raw === void 0) return [];
|
|
5207
|
+
const tokens = (Array.isArray(raw) ? raw : [raw]).flatMap(
|
|
5208
|
+
(entry) => String(entry).split(/[\s,]+/)
|
|
5209
|
+
);
|
|
5210
|
+
const seen = /* @__PURE__ */ new Set();
|
|
5211
|
+
const out = [];
|
|
5212
|
+
for (const token of tokens) {
|
|
5213
|
+
const trimmed = token.trim();
|
|
5214
|
+
if (!trimmed || seen.has(trimmed)) continue;
|
|
5215
|
+
seen.add(trimmed);
|
|
5216
|
+
out.push(trimmed);
|
|
5217
|
+
}
|
|
5218
|
+
return out;
|
|
5219
|
+
}
|
|
5220
|
+
function parseOriginList(raw) {
|
|
5221
|
+
const seen = /* @__PURE__ */ new Set();
|
|
5222
|
+
const out = [];
|
|
5223
|
+
for (const token of splitList(raw)) {
|
|
5224
|
+
const origin = normalizeFrameOrigin(token);
|
|
5225
|
+
if (!origin || seen.has(origin)) continue;
|
|
5226
|
+
seen.add(origin);
|
|
5227
|
+
out.push(origin);
|
|
5228
|
+
}
|
|
5229
|
+
return out;
|
|
5230
|
+
}
|
|
5231
|
+
function frameAncestorsHeaderValue(origins) {
|
|
5232
|
+
if (origins.length === 0) return "frame-ancestors 'none'";
|
|
5233
|
+
return `frame-ancestors ${origins.join(" ")}`;
|
|
5234
|
+
}
|
|
5235
|
+
function buildEmbedClientConfig(resolved) {
|
|
5236
|
+
if (!resolved.enabled) return void 0;
|
|
5237
|
+
const client = { enabled: true };
|
|
5238
|
+
if (resolved.views && resolved.views.length > 0) client.views = resolved.views;
|
|
5239
|
+
if (resolved.theme && Object.keys(resolved.theme).length > 0) client.theme = resolved.theme;
|
|
5240
|
+
return client;
|
|
5241
|
+
}
|
|
5242
|
+
|
|
5021
5243
|
export {
|
|
5022
5244
|
__export,
|
|
5023
5245
|
apiKeyDtoSchema,
|
|
@@ -5285,6 +5507,9 @@ export {
|
|
|
5285
5507
|
trafficEventKindSchema,
|
|
5286
5508
|
TrafficEventKinds,
|
|
5287
5509
|
trafficEventsResponseSchema,
|
|
5510
|
+
classifyTrafficPath,
|
|
5511
|
+
segmentCrawlerHits,
|
|
5512
|
+
sumInfraHits,
|
|
5288
5513
|
formatRatio,
|
|
5289
5514
|
formatNumber,
|
|
5290
5515
|
formatDate,
|
|
@@ -5312,5 +5537,9 @@ export {
|
|
|
5312
5537
|
AI_PROVIDER_INFRA_DOMAINS,
|
|
5313
5538
|
escapeLikePattern,
|
|
5314
5539
|
READ_ONLY_SCOPE,
|
|
5315
|
-
isReadOnlyKey
|
|
5540
|
+
isReadOnlyKey,
|
|
5541
|
+
splitList,
|
|
5542
|
+
parseOriginList,
|
|
5543
|
+
frameAncestorsHeaderValue,
|
|
5544
|
+
buildEmbedClientConfig
|
|
5316
5545
|
};
|
|
@@ -9,7 +9,7 @@ import {
|
|
|
9
9
|
loadConfig,
|
|
10
10
|
loadConfigRaw,
|
|
11
11
|
saveConfigPatch
|
|
12
|
-
} from "./chunk-
|
|
12
|
+
} from "./chunk-PRKBJNAG.js";
|
|
13
13
|
import {
|
|
14
14
|
CC_CACHE_DIR,
|
|
15
15
|
DUCKDB_SPEC,
|
|
@@ -104,7 +104,7 @@ import {
|
|
|
104
104
|
siteAuditPages,
|
|
105
105
|
siteAuditSnapshots,
|
|
106
106
|
usageCounters
|
|
107
|
-
} from "./chunk-
|
|
107
|
+
} from "./chunk-WEV4RH25.js";
|
|
108
108
|
import {
|
|
109
109
|
AGENT_MEMORY_VALUE_MAX_BYTES,
|
|
110
110
|
AGENT_PROVIDER_IDS,
|
|
@@ -136,6 +136,7 @@ import {
|
|
|
136
136
|
agentMemoryUpsertRequestSchema,
|
|
137
137
|
authInvalid,
|
|
138
138
|
authRequired,
|
|
139
|
+
buildEmbedClientConfig,
|
|
139
140
|
buildRunErrorFromMessages,
|
|
140
141
|
classifySkillFile,
|
|
141
142
|
coerceSkillManifest,
|
|
@@ -147,20 +148,23 @@ import {
|
|
|
147
148
|
effectiveBrandNames,
|
|
148
149
|
effectiveDomains,
|
|
149
150
|
factorStatusFromScore,
|
|
151
|
+
frameAncestorsHeaderValue,
|
|
150
152
|
hostOf,
|
|
151
153
|
isAgentProviderId,
|
|
152
154
|
isBrowserProvider,
|
|
153
155
|
isRetryableHttpError,
|
|
154
156
|
normalizeUrlPath,
|
|
155
157
|
notFound,
|
|
158
|
+
parseOriginList,
|
|
156
159
|
providerError,
|
|
157
160
|
resolveSnapshotRequestQueries,
|
|
158
161
|
serializeRunError,
|
|
159
162
|
skillsClientSchema,
|
|
163
|
+
splitList,
|
|
160
164
|
validationError,
|
|
161
165
|
winnabilityClassLabel,
|
|
162
166
|
withRetry
|
|
163
|
-
} from "./chunk-
|
|
167
|
+
} from "./chunk-LRO4CLPL.js";
|
|
164
168
|
|
|
165
169
|
// src/telemetry.ts
|
|
166
170
|
import crypto from "crypto";
|
|
@@ -2728,6 +2732,34 @@ var perplexityAdapter = {
|
|
|
2728
2732
|
}
|
|
2729
2733
|
};
|
|
2730
2734
|
|
|
2735
|
+
// src/embed.ts
|
|
2736
|
+
function resolveEmbedConfig(env, config) {
|
|
2737
|
+
const embed = config.embed;
|
|
2738
|
+
const rawEnabled = env.CANONRY_EMBED?.trim();
|
|
2739
|
+
const enabled = rawEnabled ? rawEnabled === "1" || rawEnabled.toLowerCase() === "true" : embed?.enabled === true;
|
|
2740
|
+
const allowedOrigins = env.CANONRY_EMBED_ORIGINS !== void 0 ? parseOriginList(env.CANONRY_EMBED_ORIGINS) : parseOriginList(embed?.allowOrigins);
|
|
2741
|
+
const rawViews = env.CANONRY_EMBED_VIEWS !== void 0 ? splitList(env.CANONRY_EMBED_VIEWS) : splitList(embed?.views);
|
|
2742
|
+
const views = normalizeViews(rawViews);
|
|
2743
|
+
return {
|
|
2744
|
+
enabled,
|
|
2745
|
+
allowedOrigins,
|
|
2746
|
+
...views ? { views } : {},
|
|
2747
|
+
...embed?.theme ? { theme: embed.theme } : {}
|
|
2748
|
+
};
|
|
2749
|
+
}
|
|
2750
|
+
function normalizeViews(raw) {
|
|
2751
|
+
if (raw.length === 0) return void 0;
|
|
2752
|
+
const seen = /* @__PURE__ */ new Set();
|
|
2753
|
+
const out = [];
|
|
2754
|
+
for (const view of raw) {
|
|
2755
|
+
const id = view.toLowerCase();
|
|
2756
|
+
if (seen.has(id)) continue;
|
|
2757
|
+
seen.add(id);
|
|
2758
|
+
out.push(id);
|
|
2759
|
+
}
|
|
2760
|
+
return out.length > 0 ? out : void 0;
|
|
2761
|
+
}
|
|
2762
|
+
|
|
2731
2763
|
// src/places-config.ts
|
|
2732
2764
|
var DEFAULT_TIER = "atmosphere";
|
|
2733
2765
|
var DEFAULT_REFRESH_INTERVAL_DAYS = 7;
|
|
@@ -6289,7 +6321,7 @@ function readStoredGroundingSources(rawResponse) {
|
|
|
6289
6321
|
return result;
|
|
6290
6322
|
}
|
|
6291
6323
|
async function backfillInsightsCommand(project, opts) {
|
|
6292
|
-
const { IntelligenceService: IntelligenceService2 } = await import("./intelligence-service-
|
|
6324
|
+
const { IntelligenceService: IntelligenceService2 } = await import("./intelligence-service-SO46DMGR.js");
|
|
6293
6325
|
const config = loadConfig();
|
|
6294
6326
|
const db = createClient(config.database);
|
|
6295
6327
|
migrate(db);
|
|
@@ -10538,6 +10570,8 @@ async function createServer(opts) {
|
|
|
10538
10570
|
const rawBasePath = process.env.CANONRY_BASE_PATH ?? opts.config.basePath;
|
|
10539
10571
|
const normalizedBasePath = rawBasePath ? "/" + rawBasePath.replace(/^\//, "").replace(/\/?$/, "/") : void 0;
|
|
10540
10572
|
const basePath = normalizedBasePath === "/" ? void 0 : normalizedBasePath;
|
|
10573
|
+
const embed = resolveEmbedConfig(process.env, opts.config);
|
|
10574
|
+
const embedCsp = embed.enabled ? frameAncestorsHeaderValue(embed.allowedOrigins) : void 0;
|
|
10541
10575
|
const apiPrefix = basePath ? `${basePath}api/v1` : "/api/v1";
|
|
10542
10576
|
if (opts.config.apiKey) {
|
|
10543
10577
|
const keyHash = hashApiKey(opts.config.apiKey);
|
|
@@ -11173,16 +11207,25 @@ async function createServer(opts) {
|
|
|
11173
11207
|
}
|
|
11174
11208
|
});
|
|
11175
11209
|
const dirname = path9.dirname(fileURLToPath3(import.meta.url));
|
|
11176
|
-
const assetsDir = path9.join(dirname, "..", "assets");
|
|
11210
|
+
const assetsDir = opts.assetsDir ?? path9.join(dirname, "..", "assets");
|
|
11177
11211
|
if (fs8.existsSync(assetsDir)) {
|
|
11178
11212
|
const indexPath = path9.join(assetsDir, "index.html");
|
|
11179
11213
|
const injectConfig = (html) => {
|
|
11180
11214
|
const clientConfig = {};
|
|
11181
11215
|
if (basePath) clientConfig.basePath = basePath;
|
|
11216
|
+
if (embed.enabled) {
|
|
11217
|
+
const embedClient = buildEmbedClientConfig(embed);
|
|
11218
|
+
if (embedClient) clientConfig.embed = embedClient;
|
|
11219
|
+
}
|
|
11182
11220
|
const configScript = `<script>window.__CANONRY_CONFIG__=${JSON.stringify(clientConfig)}</script>`;
|
|
11183
11221
|
const baseTag = `<base href="${basePath ?? "/"}">`;
|
|
11184
11222
|
return html.replace("<head>", `<head>${baseTag}`).replace("</head>", `${configScript}</head>`);
|
|
11185
11223
|
};
|
|
11224
|
+
const sendSpaDocument = (reply, html) => {
|
|
11225
|
+
reply.header("Cache-Control", "no-cache, must-revalidate");
|
|
11226
|
+
if (embedCsp) reply.header("Content-Security-Policy", embedCsp);
|
|
11227
|
+
return reply.type("text/html").send(injectConfig(html));
|
|
11228
|
+
};
|
|
11186
11229
|
const fastifyStatic = await import("@fastify/static");
|
|
11187
11230
|
await app.register(fastifyStatic.default, {
|
|
11188
11231
|
root: assetsDir,
|
|
@@ -11209,7 +11252,7 @@ async function createServer(opts) {
|
|
|
11209
11252
|
const serveIndex = (_request, reply) => {
|
|
11210
11253
|
if (fs8.existsSync(indexPath)) {
|
|
11211
11254
|
const html = fs8.readFileSync(indexPath, "utf-8");
|
|
11212
|
-
return reply
|
|
11255
|
+
return sendSpaDocument(reply, html);
|
|
11213
11256
|
}
|
|
11214
11257
|
return reply.status(404).send({ error: "Dashboard not built" });
|
|
11215
11258
|
};
|
|
@@ -11230,7 +11273,7 @@ async function createServer(opts) {
|
|
|
11230
11273
|
}
|
|
11231
11274
|
if (fs8.existsSync(indexPath)) {
|
|
11232
11275
|
const html = fs8.readFileSync(indexPath, "utf-8");
|
|
11233
|
-
return reply
|
|
11276
|
+
return sendSpaDocument(reply, html);
|
|
11234
11277
|
}
|
|
11235
11278
|
return reply.status(404).send({ error: "Not found" });
|
|
11236
11279
|
});
|
|
@@ -86,6 +86,7 @@ import {
|
|
|
86
86
|
classifyCitedSurface,
|
|
87
87
|
classifySkillFile,
|
|
88
88
|
classifySurfaceFromCategory,
|
|
89
|
+
classifyTrafficPath,
|
|
89
90
|
clusterByCosine,
|
|
90
91
|
coerceSkillManifest,
|
|
91
92
|
competitorBatchRequestSchema,
|
|
@@ -210,6 +211,7 @@ import {
|
|
|
210
211
|
scheduleDtoSchema,
|
|
211
212
|
scheduleUpsertRequestSchema,
|
|
212
213
|
seedCollapseWarning,
|
|
214
|
+
segmentCrawlerHits,
|
|
213
215
|
serializeRunError,
|
|
214
216
|
settingsDtoSchema,
|
|
215
217
|
siteAuditPagesResponseSchema,
|
|
@@ -222,6 +224,7 @@ import {
|
|
|
222
224
|
snapshotReportSchema,
|
|
223
225
|
snapshotRequestSchema,
|
|
224
226
|
sourceBreakdownDtoSchema,
|
|
227
|
+
sumInfraHits,
|
|
225
228
|
summarizeCheckResults,
|
|
226
229
|
surfaceClassFromCompetitorType,
|
|
227
230
|
surfaceClassLabel,
|
|
@@ -255,7 +258,7 @@ import {
|
|
|
255
258
|
wordpressSchemaDeployResultDtoSchema,
|
|
256
259
|
wordpressSchemaStatusResultDtoSchema,
|
|
257
260
|
wordpressStatusDtoSchema
|
|
258
|
-
} from "./chunk-
|
|
261
|
+
} from "./chunk-LRO4CLPL.js";
|
|
259
262
|
|
|
260
263
|
// src/intelligence-service.ts
|
|
261
264
|
import { eq as eq37, desc as desc18, asc as asc5, and as and27, ne as ne5, or as or5, inArray as inArray14, gte as gte7, lte as lte4 } from "drizzle-orm";
|
|
@@ -30625,12 +30628,19 @@ async function trafficRoutes(app, opts) {
|
|
|
30625
30628
|
return response;
|
|
30626
30629
|
});
|
|
30627
30630
|
function buildSourceDetail(projectId, row, since) {
|
|
30628
|
-
const
|
|
30631
|
+
const crawlerPathRows = app.db.select({
|
|
30632
|
+
pathNormalized: crawlerEventsHourly.pathNormalized,
|
|
30633
|
+
hits: sql11`COALESCE(SUM(${crawlerEventsHourly.hits}), 0)`
|
|
30634
|
+
}).from(crawlerEventsHourly).where(
|
|
30629
30635
|
and21(
|
|
30630
30636
|
eq27(crawlerEventsHourly.sourceId, row.id),
|
|
30631
30637
|
gte4(crawlerEventsHourly.tsHour, since)
|
|
30632
30638
|
)
|
|
30633
|
-
).
|
|
30639
|
+
).groupBy(crawlerEventsHourly.pathNormalized).all();
|
|
30640
|
+
const crawlerSegments = segmentCrawlerHits(
|
|
30641
|
+
crawlerPathRows.map((r) => ({ pathNormalized: r.pathNormalized, hits: Number(r.hits) }))
|
|
30642
|
+
);
|
|
30643
|
+
const crawlerTotal = crawlerSegments.content + crawlerSegments.sitemap + crawlerSegments.robots + crawlerSegments.asset + crawlerSegments.other;
|
|
30634
30644
|
const aiUserFetchTotals = app.db.select({ total: sql11`COALESCE(SUM(${aiUserFetchEventsHourly.hits}), 0)` }).from(aiUserFetchEventsHourly).where(
|
|
30635
30645
|
and21(
|
|
30636
30646
|
eq27(aiUserFetchEventsHourly.sourceId, row.id),
|
|
@@ -30659,7 +30669,10 @@ async function trafficRoutes(app, opts) {
|
|
|
30659
30669
|
return {
|
|
30660
30670
|
...rowToDto(row),
|
|
30661
30671
|
totals24h: {
|
|
30662
|
-
crawlerHits:
|
|
30672
|
+
crawlerHits: crawlerTotal,
|
|
30673
|
+
crawlerContentHits: crawlerSegments.content,
|
|
30674
|
+
crawlerInfraHits: sumInfraHits(crawlerSegments),
|
|
30675
|
+
crawlerSegments,
|
|
30663
30676
|
aiUserFetchHits: Number(aiUserFetchTotals?.total ?? 0),
|
|
30664
30677
|
aiReferralHits: Number(aiTotals?.total ?? 0),
|
|
30665
30678
|
sampleCount: Number(sampleTotals?.total ?? 0)
|
|
@@ -30776,6 +30789,7 @@ async function trafficRoutes(app, opts) {
|
|
|
30776
30789
|
const untilIso = until.toISOString();
|
|
30777
30790
|
const events = [];
|
|
30778
30791
|
let crawlerTotal = 0;
|
|
30792
|
+
let crawlerSegments = { content: 0, sitemap: 0, robots: 0, asset: 0, other: 0 };
|
|
30779
30793
|
let aiUserFetchTotal = 0;
|
|
30780
30794
|
let aiReferralTotal = 0;
|
|
30781
30795
|
if (kind === "all" || kind === TrafficEventKinds.crawler) {
|
|
@@ -30786,8 +30800,14 @@ async function trafficRoutes(app, opts) {
|
|
|
30786
30800
|
];
|
|
30787
30801
|
if (sourceIdParam) crawlerFilters.push(eq27(crawlerEventsHourly.sourceId, sourceIdParam));
|
|
30788
30802
|
const crawlerWhere = and21(...crawlerFilters);
|
|
30789
|
-
const
|
|
30790
|
-
|
|
30803
|
+
const pathTotals = app.db.select({
|
|
30804
|
+
pathNormalized: crawlerEventsHourly.pathNormalized,
|
|
30805
|
+
hits: sql11`COALESCE(SUM(${crawlerEventsHourly.hits}), 0)`
|
|
30806
|
+
}).from(crawlerEventsHourly).where(crawlerWhere).groupBy(crawlerEventsHourly.pathNormalized).all();
|
|
30807
|
+
crawlerSegments = segmentCrawlerHits(
|
|
30808
|
+
pathTotals.map((r) => ({ pathNormalized: r.pathNormalized, hits: Number(r.hits) }))
|
|
30809
|
+
);
|
|
30810
|
+
crawlerTotal = crawlerSegments.content + crawlerSegments.sitemap + crawlerSegments.robots + crawlerSegments.asset + crawlerSegments.other;
|
|
30791
30811
|
const rows = app.db.select().from(crawlerEventsHourly).where(crawlerWhere).orderBy(desc15(crawlerEventsHourly.tsHour)).limit(limit).all();
|
|
30792
30812
|
for (const r of rows) {
|
|
30793
30813
|
events.push({
|
|
@@ -30798,6 +30818,7 @@ async function trafficRoutes(app, opts) {
|
|
|
30798
30818
|
operator: r.operator,
|
|
30799
30819
|
verificationStatus: r.verificationStatus,
|
|
30800
30820
|
pathNormalized: r.pathNormalized,
|
|
30821
|
+
pathClass: classifyTrafficPath(r.pathNormalized),
|
|
30801
30822
|
status: r.status,
|
|
30802
30823
|
hits: r.hits
|
|
30803
30824
|
});
|
|
@@ -30861,6 +30882,9 @@ async function trafficRoutes(app, opts) {
|
|
|
30861
30882
|
windowEnd: untilIso,
|
|
30862
30883
|
totals: {
|
|
30863
30884
|
crawlerHits: crawlerTotal,
|
|
30885
|
+
crawlerContentHits: crawlerSegments.content,
|
|
30886
|
+
crawlerInfraHits: sumInfraHits(crawlerSegments),
|
|
30887
|
+
crawlerSegments,
|
|
30864
30888
|
aiUserFetchHits: aiUserFetchTotal,
|
|
30865
30889
|
aiReferralHits: aiReferralTotal
|
|
30866
30890
|
},
|