@canonry/canonry 4.157.0 → 4.158.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-D12lHs6n.js → AuditHistoryPanel-McQfjoU9.js} +1 -1
- package/assets/assets/{BacklinksPage-D2ScFYru.js → BacklinksPage-Da8y1Wv8.js} +1 -1
- package/assets/assets/{HistoryPage-jZ_I4rwX.js → HistoryPage-9MJfhRyT.js} +1 -1
- package/assets/assets/{MeasurementPropertyPage-BIdQjXJT.js → MeasurementPropertyPage-BiNAHEJW.js} +1 -1
- package/assets/assets/ProjectPage-mWSMjXrR.js +15 -0
- package/assets/assets/{RunRow-Q2X0NR74.js → RunRow-DCG2LBlS.js} +1 -1
- package/assets/assets/{RunsPage-Cw7YVsbJ.js → RunsPage-ByWA_FSk.js} +1 -1
- package/assets/assets/{SettingsPage-bFl2EXOD.js → SettingsPage-DdSeKAKF.js} +1 -1
- package/assets/assets/{TrafficPage-DJjhk7Jw.js → TrafficPage-5u8rPcBt.js} +1 -1
- package/assets/assets/{TrafficSourceDetailPage-CGKwIu9A.js → TrafficSourceDetailPage-Dm-fK87u.js} +1 -1
- package/assets/assets/{extract-error-message-BHm98tXH.js → extract-error-message-CtxkAd6E.js} +1 -1
- package/assets/assets/{index-VO6nKq5b.js → index-DUfg50Pl.js} +25 -25
- package/assets/assets/index-cXb3mfeQ.css +1 -0
- package/assets/assets/{react-sigma_core.esm.min-EzswMBkr.js → react-sigma_core.esm.min-ComIyDKi.js} +1 -1
- package/assets/index.html +2 -2
- package/dist/{chunk-AEIKAWOW.js → chunk-4VZP64GZ.js} +189 -11
- package/dist/{chunk-TRRVBTU5.js → chunk-DEVAEC2S.js} +50 -1
- package/dist/{chunk-KMTRO56O.js → chunk-LK6YFHG4.js} +1 -1
- package/dist/{chunk-MEBL4EJO.js → chunk-YP4K2KXH.js} +114 -21
- package/dist/cli.js +4 -4
- package/dist/index.js +4 -4
- package/dist/{intelligence-service-YUUPSJRC.js → intelligence-service-LQ6ZRWMF.js} +2 -2
- package/dist/mcp.js +2 -2
- package/package.json +11 -10
- package/assets/assets/ProjectPage-CLvLOOtj.js +0 -15
- package/assets/assets/index-BxegEwic.css +0 -1
|
@@ -82,6 +82,8 @@ import {
|
|
|
82
82
|
SITE_HEALTH_PATH_DEFAULT_MAX_DEPTH,
|
|
83
83
|
SITE_HEALTH_PATH_MAX_DEPTH,
|
|
84
84
|
SITE_HEALTH_PATH_MAX_VISITED_NODES,
|
|
85
|
+
SITE_HEALTH_SCANS_DEFAULT_LIMIT,
|
|
86
|
+
SITE_HEALTH_SCANS_MAX_LIMIT,
|
|
85
87
|
SITE_HEALTH_SUBGRAPH_DEFAULT_MAX_EDGES,
|
|
86
88
|
SITE_HEALTH_SUBGRAPH_DEFAULT_MAX_NODES,
|
|
87
89
|
SITE_HEALTH_SUBGRAPH_MAX_EDGES,
|
|
@@ -508,6 +510,8 @@ import {
|
|
|
508
510
|
siteCrawlSummarySchema,
|
|
509
511
|
siteHealthChangesResponseSchema,
|
|
510
512
|
siteHealthPathResponseSchema,
|
|
513
|
+
siteHealthScansResponseSchema,
|
|
514
|
+
siteHealthStateSchema,
|
|
511
515
|
siteHealthSubgraphResponseSchema,
|
|
512
516
|
snapshotDiffResponseSchema,
|
|
513
517
|
snapshotListResponseSchema,
|
|
@@ -559,7 +563,7 @@ import {
|
|
|
559
563
|
wordpressSchemaDeployResultDtoSchema,
|
|
560
564
|
wordpressSchemaStatusResultDtoSchema,
|
|
561
565
|
wordpressStatusDtoSchema
|
|
562
|
-
} from "./chunk-
|
|
566
|
+
} from "./chunk-DEVAEC2S.js";
|
|
563
567
|
|
|
564
568
|
// src/intelligence-service.ts
|
|
565
569
|
import { eq as eq58, desc as desc26, asc as asc11, and as and46, ne as ne7, or as or12, inArray as inArray20, gte as gte14, lte as lte11 } from "drizzle-orm";
|
|
@@ -8678,7 +8682,7 @@ function isOverviewRead(url) {
|
|
|
8678
8682
|
}
|
|
8679
8683
|
function isTechnicalAeoRead(url) {
|
|
8680
8684
|
const rest = projectRouteRest(url);
|
|
8681
|
-
return rest === "technical-aeo" || rest === "technical-aeo/pages" || rest === "technical-aeo/trend" || rest === "technical-aeo/crawl" || rest === "technical-aeo/graph" || rest === "technical-aeo/subgraph" || rest === "technical-aeo/path" || rest === "technical-aeo/changes" || rest === "technical-aeo/crawl/pages/audit" || rest === "technical-aeo/crawl/pages" || rest === "technical-aeo/structure" || rest === "technical-aeo/internal-links" || rest === "technical-aeo/internal-links/neighbors" || rest === "technical-aeo/dead-links";
|
|
8685
|
+
return rest === "technical-aeo" || rest === "technical-aeo/pages" || rest === "technical-aeo/trend" || rest === "technical-aeo/crawl" || rest === "technical-aeo/graph" || rest === "technical-aeo/subgraph" || rest === "technical-aeo/path" || rest === "technical-aeo/changes" || rest === "technical-aeo/crawl/pages/audit" || rest === "technical-aeo/crawl/pages" || rest === "technical-aeo/runs" || rest === "technical-aeo/structure" || rest === "technical-aeo/internal-links" || rest === "technical-aeo/internal-links/neighbors" || rest === "technical-aeo/dead-links";
|
|
8682
8686
|
}
|
|
8683
8687
|
function isReportRead(url) {
|
|
8684
8688
|
const rest = projectRouteRest(url);
|
|
@@ -27412,6 +27416,7 @@ var SCHEMA_TABLE = {
|
|
|
27412
27416
|
SiteCrawlSummaryDto: siteCrawlSummarySchema,
|
|
27413
27417
|
SiteHealthChangesResponseDto: siteHealthChangesResponseSchema,
|
|
27414
27418
|
SiteHealthPathResponseDto: siteHealthPathResponseSchema,
|
|
27419
|
+
SiteHealthScansResponseDto: siteHealthScansResponseSchema,
|
|
27415
27420
|
SiteHealthSubgraphResponseDto: siteHealthSubgraphResponseSchema,
|
|
27416
27421
|
SnapshotDiffResponse: snapshotDiffResponseSchema,
|
|
27417
27422
|
SnapshotListResponse: snapshotListResponseSchema,
|
|
@@ -33396,7 +33401,7 @@ var routeCatalog = [
|
|
|
33396
33401
|
],
|
|
33397
33402
|
responses: {
|
|
33398
33403
|
200: jsonResponse("Persisted crawl summary returned.", "SiteCrawlSummaryDto"),
|
|
33399
|
-
404: errorResponse("Project or
|
|
33404
|
+
404: errorResponse("Project or site-audit run not found. A known run that published no crawl returns 200 with the no-crawl state instead.")
|
|
33400
33405
|
}
|
|
33401
33406
|
},
|
|
33402
33407
|
{
|
|
@@ -33413,7 +33418,7 @@ var routeCatalog = [
|
|
|
33413
33418
|
],
|
|
33414
33419
|
responses: {
|
|
33415
33420
|
200: jsonResponse("Bounded Site Health graph projection returned.", "SiteCrawlGraphResponseDto"),
|
|
33416
|
-
404: errorResponse("Project or
|
|
33421
|
+
404: errorResponse("Project or site-audit run not found. A known run that published no crawl returns 200 with the no-crawl state instead.")
|
|
33417
33422
|
}
|
|
33418
33423
|
},
|
|
33419
33424
|
{
|
|
@@ -33508,6 +33513,7 @@ var routeCatalog = [
|
|
|
33508
33513
|
{ name: "inventoryEligible", in: "query", description: "Filter Canonry technical inventory eligibility (`true` or `false`).", schema: booleanSchema },
|
|
33509
33514
|
{ name: "fetchState", in: "query", description: "Filter by persisted fetch state.", schema: stringSchema },
|
|
33510
33515
|
{ name: "indexabilityState", in: "query", description: "Filter by crawler-derived indexability state; this is not Google index coverage.", schema: stringSchema },
|
|
33516
|
+
{ name: "healthState", in: "query", description: "Filter by the derived Site Health state shared with the dashboard and agents. Unlike `indexabilityState` this folds fetch state, canonical identity, and the crawler reasons into one decision, so `hidden` also covers redirects, robots blocks, non-HTML, and canonical-away pages. Values: `eligible`, `hidden`, `failed`, `unchecked`.", schema: { type: "string", enum: ["eligible", "hidden", "failed", "unchecked"] } },
|
|
33511
33517
|
{ name: "auditState", in: "query", description: "Filter by audit state.", schema: stringSchema },
|
|
33512
33518
|
{ name: "sort", in: "query", description: "Sort order. Defaults to `url`.", schema: { type: "string", enum: ["url", "path", "score-asc", "score-desc"] } },
|
|
33513
33519
|
crawlCursorParameter,
|
|
@@ -33515,7 +33521,7 @@ var routeCatalog = [
|
|
|
33515
33521
|
],
|
|
33516
33522
|
responses: {
|
|
33517
33523
|
200: jsonResponse("Crawl pages returned.", "SiteCrawlPagesResponseDto"),
|
|
33518
|
-
404: errorResponse("Project or
|
|
33524
|
+
404: errorResponse("Project or site-audit run not found. A known run that published no crawl returns 200 with the no-crawl state instead.")
|
|
33519
33525
|
}
|
|
33520
33526
|
},
|
|
33521
33527
|
{
|
|
@@ -33533,7 +33539,7 @@ var routeCatalog = [
|
|
|
33533
33539
|
],
|
|
33534
33540
|
responses: {
|
|
33535
33541
|
200: jsonResponse("Immediate crawl children returned.", "SiteCrawlStructureResponseDto"),
|
|
33536
|
-
404: errorResponse("Project or
|
|
33542
|
+
404: errorResponse("Project or site-audit run not found. A known run that published no crawl returns 200 with the no-crawl state instead.")
|
|
33537
33543
|
}
|
|
33538
33544
|
},
|
|
33539
33545
|
{
|
|
@@ -33553,7 +33559,7 @@ var routeCatalog = [
|
|
|
33553
33559
|
],
|
|
33554
33560
|
responses: {
|
|
33555
33561
|
200: jsonResponse("Internal crawl links returned.", "SiteCrawlInternalLinksResponseDto"),
|
|
33556
|
-
404: errorResponse("Project or
|
|
33562
|
+
404: errorResponse("Project or site-audit run not found. A known run that published no crawl returns 200 with the no-crawl state instead.")
|
|
33557
33563
|
}
|
|
33558
33564
|
},
|
|
33559
33565
|
{
|
|
@@ -33572,7 +33578,7 @@ var routeCatalog = [
|
|
|
33572
33578
|
responses: {
|
|
33573
33579
|
200: jsonResponse("Bounded internal-link neighborhood returned.", "SiteCrawlNeighborsResponseDto"),
|
|
33574
33580
|
400: errorResponse("A nodeKey or URL is required."),
|
|
33575
|
-
404: errorResponse("Project or
|
|
33581
|
+
404: errorResponse("Project or site-audit run not found. A known run that published no crawl returns 200 with the no-crawl state instead.")
|
|
33576
33582
|
}
|
|
33577
33583
|
},
|
|
33578
33584
|
{
|
|
@@ -33589,7 +33595,22 @@ var routeCatalog = [
|
|
|
33589
33595
|
],
|
|
33590
33596
|
responses: {
|
|
33591
33597
|
200: jsonResponse("Dead-link status and findings returned.", "SiteCrawlDeadLinksResponseDto"),
|
|
33592
|
-
404: errorResponse("Project or
|
|
33598
|
+
404: errorResponse("Project or site-audit run not found. A known run that published no crawl returns 200 with the no-crawl state instead.")
|
|
33599
|
+
}
|
|
33600
|
+
},
|
|
33601
|
+
{
|
|
33602
|
+
method: "get",
|
|
33603
|
+
path: "/api/v1/projects/{name}/technical-aeo/runs",
|
|
33604
|
+
summary: "List Site Health scan history",
|
|
33605
|
+
description: "Returns every non-probe `site-audit` run for the project, newest first, including runs still queued or running and runs that failed. `hasCrawlData` says whether that scan published a page and internal-link crawl: a legacy score-only scan is listed with `hasCrawlData=false` rather than hidden, and the crawl-scoped reads answer it with their no-crawl state instead of a 404.",
|
|
33606
|
+
tags: ["technical-aeo"],
|
|
33607
|
+
parameters: [
|
|
33608
|
+
nameParameter,
|
|
33609
|
+
{ name: "limit", in: "query", description: "Max scans returned (most recent first). Defaults to 20; max 100.", schema: { type: "integer", minimum: 1, maximum: 100 } }
|
|
33610
|
+
],
|
|
33611
|
+
responses: {
|
|
33612
|
+
200: jsonResponse("Site Health scan history returned.", "SiteHealthScansResponseDto"),
|
|
33613
|
+
404: errorResponse("Project not found.")
|
|
33593
33614
|
}
|
|
33594
33615
|
},
|
|
33595
33616
|
{
|
|
@@ -57082,6 +57103,14 @@ function parseBoundedLimit(value, fallback, max) {
|
|
|
57082
57103
|
const parsed = parsePositiveInt(value, fallback, max);
|
|
57083
57104
|
return Math.max(1, parsed);
|
|
57084
57105
|
}
|
|
57106
|
+
function parseSiteHealthState(value) {
|
|
57107
|
+
if (value === void 0 || value === "") return null;
|
|
57108
|
+
const allowed = siteHealthStateSchema.safeParse(value);
|
|
57109
|
+
if (!allowed.success) {
|
|
57110
|
+
throw validationError(`"healthState" must be one of: ${siteHealthStateSchema.options.join(", ")}`);
|
|
57111
|
+
}
|
|
57112
|
+
return allowed.data;
|
|
57113
|
+
}
|
|
57085
57114
|
function parseBoolean2(value) {
|
|
57086
57115
|
if (value === true || value === "true" || value === "1") return true;
|
|
57087
57116
|
if (value === false || value === "false" || value === "0") return false;
|
|
@@ -57317,6 +57346,16 @@ async function technicalAeoRoutes(app, opts) {
|
|
|
57317
57346
|
eq56(siteCrawlPages.attemptId, scope.attemptId),
|
|
57318
57347
|
eq56(siteCrawlPages.depth, 0)
|
|
57319
57348
|
)).orderBy(asc10(siteCrawlPages.nodeKey)).limit(1).get() ?? null;
|
|
57349
|
+
const isSurfaceableAuditRun = (projectId, runId) => Boolean(app.db.select({ id: runs.id }).from(runs).where(and44(
|
|
57350
|
+
eq56(runs.id, runId),
|
|
57351
|
+
eq56(runs.projectId, projectId),
|
|
57352
|
+
eq56(runs.kind, RunKinds["site-audit"]),
|
|
57353
|
+
inArray19(runs.status, SURFACEABLE_STATUSES),
|
|
57354
|
+
notProbeRun()
|
|
57355
|
+
)).limit(1).get());
|
|
57356
|
+
const assertKnownAuditRun = (projectId, runId) => {
|
|
57357
|
+
if (runId && !isSurfaceableAuditRun(projectId, runId)) throw notFound("Site crawl run", runId);
|
|
57358
|
+
};
|
|
57320
57359
|
const hasLegacyAudit = (projectId) => Boolean(app.db.select({ runId: siteAuditSnapshots.runId }).from(siteAuditSnapshots).innerJoin(runs, eq56(siteAuditSnapshots.runId, runs.id)).where(and44(
|
|
57321
57360
|
eq56(siteAuditSnapshots.projectId, projectId),
|
|
57322
57361
|
eq56(runs.projectId, projectId),
|
|
@@ -57437,7 +57476,7 @@ async function technicalAeoRoutes(app, opts) {
|
|
|
57437
57476
|
const target = resolveCrawl(project.id, request.query.runId);
|
|
57438
57477
|
const legacyAuditAvailable = hasLegacyAudit(project.id);
|
|
57439
57478
|
if (!target) {
|
|
57440
|
-
|
|
57479
|
+
assertKnownAuditRun(project.id, request.query.runId);
|
|
57441
57480
|
return emptyCrawlSummary(project.name, legacyAuditAvailable);
|
|
57442
57481
|
}
|
|
57443
57482
|
const snapshot = target.snapshot;
|
|
@@ -57473,11 +57512,12 @@ async function technicalAeoRoutes(app, opts) {
|
|
|
57473
57512
|
const project = resolveProject(app.db, request.params.name);
|
|
57474
57513
|
const target = resolveCrawl(project.id, request.query.runId);
|
|
57475
57514
|
if (!target) {
|
|
57476
|
-
|
|
57515
|
+
assertKnownAuditRun(project.id, request.query.runId);
|
|
57477
57516
|
return {
|
|
57478
57517
|
project: project.name,
|
|
57479
57518
|
hasCrawlData: false,
|
|
57480
57519
|
runId: null,
|
|
57520
|
+
rootNodeKey: null,
|
|
57481
57521
|
layout: { state: "unavailable", version: null, reason: "no-crawl" },
|
|
57482
57522
|
totalNodes: 0,
|
|
57483
57523
|
totalEdges: 0,
|
|
@@ -57494,6 +57534,7 @@ async function technicalAeoRoutes(app, opts) {
|
|
|
57494
57534
|
project: project.name,
|
|
57495
57535
|
hasCrawlData: true,
|
|
57496
57536
|
runId: snapshot.runId,
|
|
57537
|
+
rootNodeKey: null,
|
|
57497
57538
|
layout: { state: "unavailable", version: null, reason: "details-unavailable" },
|
|
57498
57539
|
totalNodes: 0,
|
|
57499
57540
|
totalEdges: 0,
|
|
@@ -57504,6 +57545,10 @@ async function technicalAeoRoutes(app, opts) {
|
|
|
57504
57545
|
sampled: false
|
|
57505
57546
|
};
|
|
57506
57547
|
}
|
|
57548
|
+
const rootNodeKey = rootPageInScope(
|
|
57549
|
+
{ projectId: project.id, runId: snapshot.runId, attemptId: snapshot.attemptId },
|
|
57550
|
+
snapshot.rootUrl
|
|
57551
|
+
)?.nodeKey ?? null;
|
|
57507
57552
|
const persistedLayout = app.db.select().from(siteCrawlGraphLayouts).where(and44(
|
|
57508
57553
|
eq56(siteCrawlGraphLayouts.projectId, project.id),
|
|
57509
57554
|
eq56(siteCrawlGraphLayouts.runId, snapshot.runId),
|
|
@@ -57514,6 +57559,7 @@ async function technicalAeoRoutes(app, opts) {
|
|
|
57514
57559
|
project: project.name,
|
|
57515
57560
|
hasCrawlData: true,
|
|
57516
57561
|
runId: snapshot.runId,
|
|
57562
|
+
rootNodeKey,
|
|
57517
57563
|
layout: { state: "unavailable", version: null, reason: "legacy-snapshot" },
|
|
57518
57564
|
totalNodes: 0,
|
|
57519
57565
|
totalEdges: 0,
|
|
@@ -57531,6 +57577,7 @@ async function technicalAeoRoutes(app, opts) {
|
|
|
57531
57577
|
project: project.name,
|
|
57532
57578
|
hasCrawlData: true,
|
|
57533
57579
|
runId: snapshot.runId,
|
|
57580
|
+
rootNodeKey,
|
|
57534
57581
|
layout: {
|
|
57535
57582
|
state: "unavailable",
|
|
57536
57583
|
version: null,
|
|
@@ -57611,6 +57658,7 @@ async function technicalAeoRoutes(app, opts) {
|
|
|
57611
57658
|
project: project.name,
|
|
57612
57659
|
hasCrawlData: true,
|
|
57613
57660
|
runId: snapshot.runId,
|
|
57661
|
+
rootNodeKey,
|
|
57614
57662
|
layout: { state: "ready", version: persistedLayout.layoutVersion, computedAt: persistedLayout.createdAt },
|
|
57615
57663
|
totalNodes,
|
|
57616
57664
|
totalEdges,
|
|
@@ -57655,7 +57703,7 @@ async function technicalAeoRoutes(app, opts) {
|
|
|
57655
57703
|
truncated: false
|
|
57656
57704
|
});
|
|
57657
57705
|
if (!target) {
|
|
57658
|
-
|
|
57706
|
+
assertKnownAuditRun(project.id, request.query.runId);
|
|
57659
57707
|
return empty("no-crawl", null, false, false, null);
|
|
57660
57708
|
}
|
|
57661
57709
|
const snapshot = target.snapshot;
|
|
@@ -57781,7 +57829,7 @@ async function technicalAeoRoutes(app, opts) {
|
|
|
57781
57829
|
}
|
|
57782
57830
|
const target = resolveCrawl(project.id, request.query.runId);
|
|
57783
57831
|
if (!target) {
|
|
57784
|
-
|
|
57832
|
+
assertKnownAuditRun(project.id, request.query.runId);
|
|
57785
57833
|
return {
|
|
57786
57834
|
project: project.name,
|
|
57787
57835
|
runId: null,
|
|
@@ -58253,7 +58301,7 @@ async function technicalAeoRoutes(app, opts) {
|
|
|
58253
58301
|
}
|
|
58254
58302
|
const target = resolveCrawl(project.id, runId);
|
|
58255
58303
|
if (!target) {
|
|
58256
|
-
|
|
58304
|
+
assertKnownAuditRun(project.id, runId);
|
|
58257
58305
|
return { state: "no-crawl", project: project.name, runId: null };
|
|
58258
58306
|
}
|
|
58259
58307
|
const snapshot = target.snapshot;
|
|
@@ -58294,7 +58342,7 @@ async function technicalAeoRoutes(app, opts) {
|
|
|
58294
58342
|
const project = resolveProject(app.db, request.params.name);
|
|
58295
58343
|
const target = resolveCrawl(project.id, request.query.runId);
|
|
58296
58344
|
if (!target) {
|
|
58297
|
-
|
|
58345
|
+
assertKnownAuditRun(project.id, request.query.runId);
|
|
58298
58346
|
return { project: project.name, hasCrawlData: false, runId: null, total: 0, nextCursor: null, pages: [] };
|
|
58299
58347
|
}
|
|
58300
58348
|
const snapshot = target.snapshot;
|
|
@@ -58311,12 +58359,25 @@ async function technicalAeoRoutes(app, opts) {
|
|
|
58311
58359
|
if (request.query.fetchState) filters.push(eq56(siteCrawlPages.fetchState, request.query.fetchState));
|
|
58312
58360
|
if (request.query.indexabilityState) filters.push(eq56(siteCrawlPages.indexabilityState, request.query.indexabilityState));
|
|
58313
58361
|
if (request.query.auditState) filters.push(eq56(siteCrawlPages.auditState, request.query.auditState));
|
|
58362
|
+
const healthState = parseSiteHealthState(request.query.healthState);
|
|
58314
58363
|
const where = and44(...filters);
|
|
58315
|
-
const total = app.db.select({ value: count() }).from(siteCrawlPages).where(where).get()?.value ?? 0;
|
|
58316
58364
|
const limit = parseBoundedLimit(request.query.limit, 100, 200);
|
|
58317
58365
|
const offset = decodeCursor(request.query.cursor);
|
|
58318
58366
|
const orderBy = request.query.sort === "score-desc" ? [desc24(siteCrawlPages.auditScore), asc10(siteCrawlPages.nodeKey)] : request.query.sort === "score-asc" ? [asc10(siteCrawlPages.auditScore), asc10(siteCrawlPages.nodeKey)] : request.query.sort === "path" ? [asc10(siteCrawlPages.path), asc10(siteCrawlPages.nodeKey)] : [asc10(siteCrawlPages.url), asc10(siteCrawlPages.nodeKey)];
|
|
58319
|
-
|
|
58367
|
+
let total;
|
|
58368
|
+
let rows;
|
|
58369
|
+
if (healthState) {
|
|
58370
|
+
const candidates = app.db.select().from(siteCrawlPages).where(where).orderBy(...orderBy).limit(MAX_STRUCTURE_SOURCE_ROWS + 1).all();
|
|
58371
|
+
if (candidates.length > MAX_STRUCTURE_SOURCE_ROWS) {
|
|
58372
|
+
throw validationError(`Persisted crawl exceeds the ${MAX_STRUCTURE_SOURCE_ROWS}-page health-state filter limit`);
|
|
58373
|
+
}
|
|
58374
|
+
const matching = candidates.filter((row) => deriveSiteHealthState(row) === healthState);
|
|
58375
|
+
total = matching.length;
|
|
58376
|
+
rows = matching.slice(offset, offset + limit);
|
|
58377
|
+
} else {
|
|
58378
|
+
total = app.db.select({ value: count() }).from(siteCrawlPages).where(where).get()?.value ?? 0;
|
|
58379
|
+
rows = app.db.select().from(siteCrawlPages).where(where).orderBy(...orderBy).limit(limit).offset(offset).all();
|
|
58380
|
+
}
|
|
58320
58381
|
const nextOffset = offset + rows.length;
|
|
58321
58382
|
return {
|
|
58322
58383
|
project: project.name,
|
|
@@ -58332,7 +58393,7 @@ async function technicalAeoRoutes(app, opts) {
|
|
|
58332
58393
|
const parentPath = normalizeParentPath(request.query.parentPath);
|
|
58333
58394
|
const target = resolveCrawl(project.id, request.query.runId);
|
|
58334
58395
|
if (!target) {
|
|
58335
|
-
|
|
58396
|
+
assertKnownAuditRun(project.id, request.query.runId);
|
|
58336
58397
|
return { project: project.name, hasCrawlData: false, runId: null, parentPath, nextCursor: null, children: [] };
|
|
58337
58398
|
}
|
|
58338
58399
|
const snapshot = target.snapshot;
|
|
@@ -58398,7 +58459,7 @@ async function technicalAeoRoutes(app, opts) {
|
|
|
58398
58459
|
const project = resolveProject(app.db, request.params.name);
|
|
58399
58460
|
const target = resolveCrawl(project.id, request.query.runId);
|
|
58400
58461
|
if (!target) {
|
|
58401
|
-
|
|
58462
|
+
assertKnownAuditRun(project.id, request.query.runId);
|
|
58402
58463
|
return { project: project.name, hasCrawlData: false, runId: null, total: 0, nextCursor: null, edges: [] };
|
|
58403
58464
|
}
|
|
58404
58465
|
const snapshot = target.snapshot;
|
|
@@ -58437,7 +58498,7 @@ async function technicalAeoRoutes(app, opts) {
|
|
|
58437
58498
|
}
|
|
58438
58499
|
const target = resolveCrawl(project.id, request.query.runId);
|
|
58439
58500
|
if (!target) {
|
|
58440
|
-
|
|
58501
|
+
assertKnownAuditRun(project.id, request.query.runId);
|
|
58441
58502
|
return {
|
|
58442
58503
|
project: project.name,
|
|
58443
58504
|
hasCrawlData: false,
|
|
@@ -58492,7 +58553,7 @@ async function technicalAeoRoutes(app, opts) {
|
|
|
58492
58553
|
const target = resolveCrawl(project.id, request.query.runId);
|
|
58493
58554
|
const legacyAuditAvailable = hasLegacyAudit(project.id);
|
|
58494
58555
|
if (!target) {
|
|
58495
|
-
|
|
58556
|
+
assertKnownAuditRun(project.id, request.query.runId);
|
|
58496
58557
|
return { project: project.name, runId: null, state: "unavailable", legacyAuditAvailable };
|
|
58497
58558
|
}
|
|
58498
58559
|
const snapshot = target.snapshot;
|
|
@@ -58538,6 +58599,38 @@ async function technicalAeoRoutes(app, opts) {
|
|
|
58538
58599
|
deadLinks
|
|
58539
58600
|
};
|
|
58540
58601
|
});
|
|
58602
|
+
app.get("/projects/:name/technical-aeo/runs", async (request) => {
|
|
58603
|
+
const project = resolveProject(app.db, request.params.name);
|
|
58604
|
+
const limit = parseBoundedLimit(request.query.limit, SITE_HEALTH_SCANS_DEFAULT_LIMIT, SITE_HEALTH_SCANS_MAX_LIMIT);
|
|
58605
|
+
const rows = app.db.select({
|
|
58606
|
+
runId: runs.id,
|
|
58607
|
+
status: runs.status,
|
|
58608
|
+
createdAt: runs.createdAt,
|
|
58609
|
+
startedAt: runs.startedAt,
|
|
58610
|
+
finishedAt: runs.finishedAt
|
|
58611
|
+
}).from(runs).where(and44(
|
|
58612
|
+
eq56(runs.projectId, project.id),
|
|
58613
|
+
eq56(runs.kind, RunKinds["site-audit"]),
|
|
58614
|
+
notProbeRun()
|
|
58615
|
+
)).orderBy(desc24(runs.createdAt), desc24(runs.id)).limit(limit).all();
|
|
58616
|
+
const runIds = rows.map((row) => row.runId);
|
|
58617
|
+
const crawlRunIds = new Set(runIds.length === 0 ? [] : app.db.select({ runId: siteCrawlSnapshots.runId }).from(siteCrawlSnapshots).innerJoin(runs, eq56(siteCrawlSnapshots.runId, runs.id)).where(and44(
|
|
58618
|
+
eq56(siteCrawlSnapshots.projectId, project.id),
|
|
58619
|
+
eq56(runs.projectId, project.id),
|
|
58620
|
+
eq56(runs.kind, RunKinds["site-audit"]),
|
|
58621
|
+
inArray19(runs.status, SURFACEABLE_STATUSES),
|
|
58622
|
+
notProbeRun(),
|
|
58623
|
+
inArray19(siteCrawlSnapshots.runId, runIds)
|
|
58624
|
+
)).all().map((row) => row.runId));
|
|
58625
|
+
return {
|
|
58626
|
+
project: project.name,
|
|
58627
|
+
scans: rows.map((row) => ({
|
|
58628
|
+
...row,
|
|
58629
|
+
status: row.status,
|
|
58630
|
+
hasCrawlData: crawlRunIds.has(row.runId)
|
|
58631
|
+
}))
|
|
58632
|
+
};
|
|
58633
|
+
});
|
|
58541
58634
|
app.post("/projects/:name/technical-aeo/runs", async (request) => {
|
|
58542
58635
|
const project = resolveProject(app.db, request.params.name);
|
|
58543
58636
|
const parsed = siteAuditRunRequestSchema.safeParse(request.body ?? {});
|
package/dist/cli.js
CHANGED
|
@@ -31,7 +31,7 @@ import {
|
|
|
31
31
|
showFirstRunNotice,
|
|
32
32
|
trackCliCommandFinished,
|
|
33
33
|
trackEvent
|
|
34
|
-
} from "./chunk-
|
|
34
|
+
} from "./chunk-4VZP64GZ.js";
|
|
35
35
|
import {
|
|
36
36
|
CliError,
|
|
37
37
|
EXIT_SYSTEM_ERROR,
|
|
@@ -51,7 +51,7 @@ import {
|
|
|
51
51
|
saveConfigPatch,
|
|
52
52
|
systemError,
|
|
53
53
|
usageError
|
|
54
|
-
} from "./chunk-
|
|
54
|
+
} from "./chunk-LK6YFHG4.js";
|
|
55
55
|
import {
|
|
56
56
|
CLOUDFLARE_WORKER_BINDINGS,
|
|
57
57
|
CLOUDFLARE_WORKER_GENERATED_MARKER,
|
|
@@ -65,7 +65,7 @@ import {
|
|
|
65
65
|
projects,
|
|
66
66
|
queries,
|
|
67
67
|
renderReportHtml
|
|
68
|
-
} from "./chunk-
|
|
68
|
+
} from "./chunk-YP4K2KXH.js";
|
|
69
69
|
import {
|
|
70
70
|
AdsDeliverySnapshotStatuses,
|
|
71
71
|
AdsHistoricalCampaignRollupStatuses,
|
|
@@ -129,7 +129,7 @@ import {
|
|
|
129
129
|
providerQuotaPolicySchema,
|
|
130
130
|
resolveProviderInput,
|
|
131
131
|
winnabilityClassSchema
|
|
132
|
-
} from "./chunk-
|
|
132
|
+
} from "./chunk-DEVAEC2S.js";
|
|
133
133
|
|
|
134
134
|
// src/cli.ts
|
|
135
135
|
import { pathToFileURL } from "url";
|
package/dist/index.js
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import {
|
|
2
2
|
createServer
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-4VZP64GZ.js";
|
|
4
4
|
import {
|
|
5
5
|
loadConfig
|
|
6
|
-
} from "./chunk-
|
|
7
|
-
import "./chunk-
|
|
8
|
-
import "./chunk-
|
|
6
|
+
} from "./chunk-LK6YFHG4.js";
|
|
7
|
+
import "./chunk-YP4K2KXH.js";
|
|
8
|
+
import "./chunk-DEVAEC2S.js";
|
|
9
9
|
export {
|
|
10
10
|
createServer,
|
|
11
11
|
loadConfig
|
package/dist/mcp.js
CHANGED
|
@@ -3,10 +3,10 @@ import {
|
|
|
3
3
|
PACKAGE_VERSION,
|
|
4
4
|
canonryMcpTools,
|
|
5
5
|
createApiClient
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-LK6YFHG4.js";
|
|
7
7
|
import {
|
|
8
8
|
isReadOnlyKey
|
|
9
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-DEVAEC2S.js";
|
|
10
10
|
|
|
11
11
|
// src/mcp/cli.ts
|
|
12
12
|
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@canonry/canonry",
|
|
3
|
-
"version": "4.
|
|
3
|
+
"version": "4.158.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Agent-first open-source AEO operating platform - track how answer engines cite your domain",
|
|
6
6
|
"license": "FSL-1.1-ALv2",
|
|
@@ -39,8 +39,8 @@
|
|
|
39
39
|
"node": ">=22.14.0 <26"
|
|
40
40
|
},
|
|
41
41
|
"dependencies": {
|
|
42
|
-
"@canonry/aeo-audit": "4.6.2",
|
|
43
42
|
"@anthropic-ai/sdk": "^0.91.1",
|
|
43
|
+
"@canonry/aeo-audit": "4.6.2",
|
|
44
44
|
"@fastify/rate-limit": "^11.2.0",
|
|
45
45
|
"@fastify/static": "^9.1.1",
|
|
46
46
|
"@google/genai": "^1.46.0",
|
|
@@ -55,6 +55,7 @@
|
|
|
55
55
|
"fastify": "^5.8.5",
|
|
56
56
|
"graphology": "0.26.0",
|
|
57
57
|
"graphology-layout-forceatlas2": "0.10.1",
|
|
58
|
+
"graphology-layout-noverlap": "0.4.2",
|
|
58
59
|
"node-cron": "^4.2.1",
|
|
59
60
|
"openai": "^6.0.0",
|
|
60
61
|
"pdf-lib": "^1.17.1",
|
|
@@ -70,24 +71,24 @@
|
|
|
70
71
|
"tsx": "^4.19.0",
|
|
71
72
|
"@ainyc/canonry-api-client": "0.0.0",
|
|
72
73
|
"@ainyc/canonry-config": "0.0.0",
|
|
73
|
-
"@ainyc/canonry-contracts": "0.0.0",
|
|
74
|
-
"@ainyc/canonry-api-routes": "0.0.0",
|
|
75
74
|
"@ainyc/canonry-db": "0.0.0",
|
|
76
|
-
"@ainyc/canonry-
|
|
75
|
+
"@ainyc/canonry-api-routes": "0.0.0",
|
|
76
|
+
"@ainyc/canonry-contracts": "0.0.0",
|
|
77
77
|
"@ainyc/canonry-integration-bing": "0.0.0",
|
|
78
78
|
"@ainyc/canonry-integration-openai-ads": "0.0.0",
|
|
79
|
+
"@ainyc/canonry-integration-cloudflare-worker": "0.0.0",
|
|
80
|
+
"@ainyc/canonry-integration-cloud-run": "0.0.0",
|
|
79
81
|
"@ainyc/canonry-integration-commoncrawl": "0.0.0",
|
|
80
|
-
"@ainyc/canonry-integration-google-business-profile": "0.0.0",
|
|
81
82
|
"@ainyc/canonry-integration-google": "0.0.0",
|
|
83
|
+
"@ainyc/canonry-integration-google-business-profile": "0.0.0",
|
|
82
84
|
"@ainyc/canonry-integration-google-places": "0.0.0",
|
|
83
|
-
"@ainyc/canonry-integration-wordpress": "0.0.0",
|
|
84
85
|
"@ainyc/canonry-intelligence": "0.0.0",
|
|
85
|
-
"@ainyc/canonry-integration-traffic": "0.0.0",
|
|
86
|
-
"@ainyc/canonry-integration-cloud-run": "0.0.0",
|
|
87
|
-
"@ainyc/canonry-provider-cdp": "0.0.0",
|
|
88
86
|
"@ainyc/canonry-provider-claude": "0.0.0",
|
|
87
|
+
"@ainyc/canonry-integration-wordpress": "0.0.0",
|
|
89
88
|
"@ainyc/canonry-provider-gemini": "0.0.0",
|
|
89
|
+
"@ainyc/canonry-provider-cdp": "0.0.0",
|
|
90
90
|
"@ainyc/canonry-provider-local": "0.0.0",
|
|
91
|
+
"@ainyc/canonry-integration-traffic": "0.0.0",
|
|
91
92
|
"@ainyc/canonry-provider-openai": "0.0.0",
|
|
92
93
|
"@ainyc/canonry-provider-perplexity": "0.0.0"
|
|
93
94
|
},
|