@ainyc/canonry 4.187.0 → 4.188.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 +5 -1
- package/assets/assets/{AuditHistoryPanel-G2iVWlbn.js → AuditHistoryPanel-BCpFULQp.js} +1 -1
- package/assets/assets/{BacklinksPage-B13UlDT7.js → BacklinksPage-CFHiZFhZ.js} +1 -1
- package/assets/assets/{HistoryPage-DZoRKfzJ.js → HistoryPage-THnDCEnv.js} +1 -1
- package/assets/assets/{MeasurementPropertyPage-DNxsAgEA.js → MeasurementPropertyPage-DWWwA2kL.js} +1 -1
- package/assets/assets/ProjectPage-CP57_Lqf.js +9 -0
- package/assets/assets/{RunRow-C9u35nrm.js → RunRow-CDWArf9X.js} +1 -1
- package/assets/assets/{RunsPage-DST-BpAu.js → RunsPage-Ctsw14Vg.js} +1 -1
- package/assets/assets/{SettingsPage-BC05JomS.js → SettingsPage-IHYGgD0e.js} +1 -1
- package/assets/assets/{SiteHealthSection-DIeYA2HJ.js → SiteHealthSection-DjFHZqBF.js} +3 -3
- package/assets/assets/{TrafficPage-DezdhoxL.js → TrafficPage-Cb1Zwgc5.js} +1 -1
- package/assets/assets/{TrafficSourceDetailPage-C0FIPjXi.js → TrafficSourceDetailPage-CRdjdiAa.js} +1 -1
- package/assets/assets/{extract-error-message-B5OYNTJO.js → extract-error-message-CNs6e1oz.js} +1 -1
- package/assets/assets/{index-DJWMbOc5.js → index-B64f9mVI.js} +29 -29
- package/assets/assets/index-DTblya6d.css +1 -0
- package/assets/assets/{react-sigma_core.esm.min-B06R8tYw.js → react-sigma_core.esm.min-CzJ-HG1j.js} +1 -1
- package/assets/index.html +2 -2
- package/dist/{chunk-B7WQ5Z4L.js → chunk-6YJQGOR6.js} +6 -5
- package/dist/{chunk-IPALTNIE.js → chunk-A47HAZDJ.js} +2 -2
- package/dist/{chunk-EMSDPSQM.js → chunk-GPTEXYYL.js} +116 -62
- package/dist/{chunk-LNBX7RTN.js → chunk-HIIOVQSH.js} +30 -1
- package/dist/{chunk-5BUAG4CN.js → chunk-QPYMAXLJ.js} +37 -1
- package/dist/cli.js +32 -5
- package/dist/index.js +4 -4
- package/dist/{intelligence-service-UZGA24EF.js → intelligence-service-4KMWHEYP.js} +2 -2
- package/dist/mcp.js +3 -3
- package/package.json +13 -13
- package/assets/assets/ProjectPage-BdfsfLkU.js +0 -9
- package/assets/assets/index-DJ8_LvRn.css +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-B64f9mVI.js"></script>
|
|
16
16
|
<link rel="modulepreload" crossorigin href="./assets/vendor-tanstack-CYBjbqVr.js">
|
|
17
17
|
<link rel="modulepreload" crossorigin href="./assets/vendor-radix-BpmvLvpp.js">
|
|
18
18
|
<link rel="modulepreload" crossorigin href="./assets/vendor-recharts-FA0uySU7.js">
|
|
19
19
|
<link rel="modulepreload" crossorigin href="./assets/vendor-lucide-BovNTc41.js">
|
|
20
20
|
<link rel="modulepreload" crossorigin href="./assets/vendor-markdown-9tTeP8v7.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-DTblya6d.css">
|
|
23
23
|
</head>
|
|
24
24
|
<body>
|
|
25
25
|
<div id="root"></div>
|
|
@@ -13,7 +13,7 @@ import {
|
|
|
13
13
|
loadConfig,
|
|
14
14
|
loadConfigRaw,
|
|
15
15
|
saveConfigPatch
|
|
16
|
-
} from "./chunk-
|
|
16
|
+
} from "./chunk-QPYMAXLJ.js";
|
|
17
17
|
import {
|
|
18
18
|
CC_CACHE_DIR,
|
|
19
19
|
DUCKDB_SPEC,
|
|
@@ -160,7 +160,7 @@ import {
|
|
|
160
160
|
siteCrawlSnapshots,
|
|
161
161
|
toAlertView,
|
|
162
162
|
usageCounters
|
|
163
|
-
} from "./chunk-
|
|
163
|
+
} from "./chunk-GPTEXYYL.js";
|
|
164
164
|
import {
|
|
165
165
|
AGENT_MEMORY_VALUE_MAX_BYTES,
|
|
166
166
|
AGENT_PROVIDER_IDS,
|
|
@@ -302,7 +302,7 @@ import {
|
|
|
302
302
|
validationError,
|
|
303
303
|
winnabilityClassLabel,
|
|
304
304
|
withRetry
|
|
305
|
-
} from "./chunk-
|
|
305
|
+
} from "./chunk-HIIOVQSH.js";
|
|
306
306
|
|
|
307
307
|
// src/telemetry.ts
|
|
308
308
|
import crypto from "crypto";
|
|
@@ -11924,7 +11924,7 @@ function readStoredGroundingSources(rawResponse) {
|
|
|
11924
11924
|
return result;
|
|
11925
11925
|
}
|
|
11926
11926
|
async function backfillInsightsCommand(project, opts) {
|
|
11927
|
-
const { IntelligenceService: IntelligenceService2 } = await import("./intelligence-service-
|
|
11927
|
+
const { IntelligenceService: IntelligenceService2 } = await import("./intelligence-service-4KMWHEYP.js");
|
|
11928
11928
|
const config = loadConfig();
|
|
11929
11929
|
const db = createClient(config.database);
|
|
11930
11930
|
migrate(db);
|
|
@@ -13996,7 +13996,8 @@ function mcpToAgentTool(tool, ctx) {
|
|
|
13996
13996
|
};
|
|
13997
13997
|
}
|
|
13998
13998
|
var AERO_EXCLUDED_MCP_TOOLS = /* @__PURE__ */ new Set([
|
|
13999
|
-
CanonryMcpToolNames.canonry_agent_clear
|
|
13999
|
+
CanonryMcpToolNames.canonry_agent_clear,
|
|
14000
|
+
CanonryMcpToolNames.canonry_results_clear
|
|
14000
14001
|
]);
|
|
14001
14002
|
function buildMcpAgentTools(registry, ctx, opts = {}) {
|
|
14002
14003
|
return registry.filter((tool) => !AERO_EXCLUDED_MCP_TOOLS.has(tool.name)).filter((tool) => opts.includeNames ? opts.includeNames.has(tool.name) : true).filter((tool) => opts.readOnly ? tool.access === "read" : true).map((tool) => mcpToAgentTool(tool, ctx));
|
|
@@ -5,11 +5,11 @@ import {
|
|
|
5
5
|
installSkills,
|
|
6
6
|
loadConfigRaw,
|
|
7
7
|
saveConfigPatch
|
|
8
|
-
} from "./chunk-
|
|
8
|
+
} from "./chunk-QPYMAXLJ.js";
|
|
9
9
|
import {
|
|
10
10
|
SKILL_MANIFEST_FILENAME,
|
|
11
11
|
SkillsClients
|
|
12
|
-
} from "./chunk-
|
|
12
|
+
} from "./chunk-HIIOVQSH.js";
|
|
13
13
|
|
|
14
14
|
// src/skills-autosync.ts
|
|
15
15
|
import fs from "fs";
|
|
@@ -564,6 +564,8 @@ import {
|
|
|
564
564
|
resolveMeasurementRunQueryScope,
|
|
565
565
|
resolveMeasurementRunScope,
|
|
566
566
|
resolveSnapshotRequestQueries,
|
|
567
|
+
resultsClearRequestSchema,
|
|
568
|
+
resultsClearResponseSchema,
|
|
567
569
|
resultsExportDtoSchema,
|
|
568
570
|
retryAfterDelayMs,
|
|
569
571
|
runDetailDtoSchema,
|
|
@@ -668,7 +670,7 @@ import {
|
|
|
668
670
|
wordpressSchemaDeployResultDtoSchema,
|
|
669
671
|
wordpressSchemaStatusResultDtoSchema,
|
|
670
672
|
wordpressStatusDtoSchema
|
|
671
|
-
} from "./chunk-
|
|
673
|
+
} from "./chunk-HIIOVQSH.js";
|
|
672
674
|
|
|
673
675
|
// src/intelligence-service.ts
|
|
674
676
|
import { eq as eq67, desc as desc29, asc as asc12, and as and56, ne as ne10, or as or14, inArray as inArray25, gte as gte18, lte as lte15, isNull as isNull12, sql as sql26, exists } from "drizzle-orm";
|
|
@@ -9179,15 +9181,15 @@ function buildAiSourceOrigin(snapshots, projectDomains, competitorDomains, topDo
|
|
|
9179
9181
|
totalCitations++;
|
|
9180
9182
|
}
|
|
9181
9183
|
}
|
|
9182
|
-
const categories = [...categoryCounts.entries()].map(([category, { label, count:
|
|
9184
|
+
const categories = [...categoryCounts.entries()].map(([category, { label, count: count4 }]) => ({
|
|
9183
9185
|
category,
|
|
9184
9186
|
label,
|
|
9185
|
-
count:
|
|
9186
|
-
sharePct: totalCitations > 0 ? Math.round(
|
|
9187
|
+
count: count4,
|
|
9188
|
+
sharePct: totalCitations > 0 ? Math.round(count4 / totalCitations * 100) : 0
|
|
9187
9189
|
})).sort((a, b) => b.count - a.count);
|
|
9188
|
-
const topDomains = [...domainCounts.entries()].map(([domain,
|
|
9190
|
+
const topDomains = [...domainCounts.entries()].map(([domain, count4]) => ({
|
|
9189
9191
|
domain,
|
|
9190
|
-
count:
|
|
9192
|
+
count: count4,
|
|
9191
9193
|
isCompetitor: citedDomainBelongsToProject(domain, competitorDomains)
|
|
9192
9194
|
})).sort((a, b) => b.count - a.count).slice(0, topDomainsLimit);
|
|
9193
9195
|
return { categories, topDomains };
|
|
@@ -12019,7 +12021,7 @@ async function projectRoutes(app, opts) {
|
|
|
12019
12021
|
app.get("/projects/:name/delete-preview", async (request, reply) => {
|
|
12020
12022
|
const project = resolveProject(app.db, request.params.name);
|
|
12021
12023
|
const pid = project.id;
|
|
12022
|
-
const
|
|
12024
|
+
const count4 = (n) => n ?? 0;
|
|
12023
12025
|
const queryCount = app.db.select({ n: sql4`count(*)` }).from(queries).where(eq5(queries.projectId, pid)).get();
|
|
12024
12026
|
const competitorCount = app.db.select({ n: sql4`count(*)` }).from(competitors).where(eq5(competitors.projectId, pid)).get();
|
|
12025
12027
|
const runCount = app.db.select({ n: sql4`count(*)` }).from(runs).where(eq5(runs.projectId, pid)).get();
|
|
@@ -12029,14 +12031,14 @@ async function projectRoutes(app, opts) {
|
|
|
12029
12031
|
return reply.send({
|
|
12030
12032
|
project: { id: project.id, name: project.name },
|
|
12031
12033
|
cascadeRows: {
|
|
12032
|
-
queries:
|
|
12033
|
-
competitors:
|
|
12034
|
-
runs:
|
|
12035
|
-
snapshots:
|
|
12036
|
-
insights:
|
|
12034
|
+
queries: count4(queryCount?.n),
|
|
12035
|
+
competitors: count4(competitorCount?.n),
|
|
12036
|
+
runs: count4(runCount?.n),
|
|
12037
|
+
snapshots: count4(snapshotCount?.n),
|
|
12038
|
+
insights: count4(insightCount?.n)
|
|
12037
12039
|
},
|
|
12038
12040
|
detachedRows: {
|
|
12039
|
-
auditLog:
|
|
12041
|
+
auditLog: count4(auditLogCount?.n)
|
|
12040
12042
|
}
|
|
12041
12043
|
});
|
|
12042
12044
|
});
|
|
@@ -12722,14 +12724,14 @@ async function queryRoutes(app, opts) {
|
|
|
12722
12724
|
validProviders: validNames
|
|
12723
12725
|
});
|
|
12724
12726
|
}
|
|
12725
|
-
const
|
|
12727
|
+
const count4 = body.count ?? 5;
|
|
12726
12728
|
if (!opts.onGenerateQueries) {
|
|
12727
12729
|
throw notImplemented("Query generation is not supported in this deployment");
|
|
12728
12730
|
}
|
|
12729
12731
|
const existingRows = app.db.select().from(queries).where(eq8(queries.projectId, project.id)).all();
|
|
12730
12732
|
const existingQueries = existingRows.map((r) => r.query);
|
|
12731
12733
|
try {
|
|
12732
|
-
const generated = await opts.onGenerateQueries(provider,
|
|
12734
|
+
const generated = await opts.onGenerateQueries(provider, count4, {
|
|
12733
12735
|
domain: project.canonicalDomain,
|
|
12734
12736
|
displayName: project.displayName,
|
|
12735
12737
|
country: project.country,
|
|
@@ -12855,14 +12857,14 @@ async function queryRoutes(app, opts) {
|
|
|
12855
12857
|
validProviders: validNames
|
|
12856
12858
|
});
|
|
12857
12859
|
}
|
|
12858
|
-
const
|
|
12860
|
+
const count4 = body.count ?? 5;
|
|
12859
12861
|
if (!opts.onGenerateQueries) {
|
|
12860
12862
|
throw notImplemented("Keyword generation is not supported in this deployment");
|
|
12861
12863
|
}
|
|
12862
12864
|
const existingRows = app.db.select().from(queries).where(eq8(queries.projectId, project.id)).all();
|
|
12863
12865
|
const existingQueries = existingRows.map((r) => r.query);
|
|
12864
12866
|
try {
|
|
12865
|
-
const generated = await opts.onGenerateQueries(provider,
|
|
12867
|
+
const generated = await opts.onGenerateQueries(provider, count4, {
|
|
12866
12868
|
domain: project.canonicalDomain,
|
|
12867
12869
|
displayName: project.displayName,
|
|
12868
12870
|
country: project.country,
|
|
@@ -18706,19 +18708,19 @@ function groupChangesFromRows(rows, identities) {
|
|
|
18706
18708
|
});
|
|
18707
18709
|
}
|
|
18708
18710
|
function countsFromRows(rows, groupChanges) {
|
|
18709
|
-
const
|
|
18710
|
-
const ambiguousRows =
|
|
18711
|
-
const unmatchedRows =
|
|
18712
|
-
const invalidRows =
|
|
18713
|
-
const proposedRows =
|
|
18714
|
-
const excludedRows =
|
|
18711
|
+
const count4 = (status) => rows.filter((row) => row.status === status).length;
|
|
18712
|
+
const ambiguousRows = count4("ambiguous");
|
|
18713
|
+
const unmatchedRows = count4("unmatched");
|
|
18714
|
+
const invalidRows = count4("invalid");
|
|
18715
|
+
const proposedRows = count4("proposed");
|
|
18716
|
+
const excludedRows = count4("excluded");
|
|
18715
18717
|
return {
|
|
18716
18718
|
dataRows: rows.length,
|
|
18717
|
-
matchedRows:
|
|
18719
|
+
matchedRows: count4("matched"),
|
|
18718
18720
|
ambiguousRows,
|
|
18719
18721
|
unmatchedRows,
|
|
18720
18722
|
invalidRows,
|
|
18721
|
-
duplicateRows:
|
|
18723
|
+
duplicateRows: count4("duplicate"),
|
|
18722
18724
|
proposedRows,
|
|
18723
18725
|
excludedRows,
|
|
18724
18726
|
needsAttention: ambiguousRows + unmatchedRows + invalidRows + proposedRows + excludedRows,
|
|
@@ -24080,9 +24082,9 @@ function workloadDiff(before, after) {
|
|
|
24080
24082
|
nextSweepNodes: after.size,
|
|
24081
24083
|
nextSweepProviderCalls: sum(after.values()),
|
|
24082
24084
|
addedNodes: added.length,
|
|
24083
|
-
addedProviderCalls: sum(added.map(([,
|
|
24085
|
+
addedProviderCalls: sum(added.map(([, count4]) => count4)),
|
|
24084
24086
|
removedNodes: removed.length,
|
|
24085
|
-
removedProviderCalls: sum(removed.map(([,
|
|
24087
|
+
removedProviderCalls: sum(removed.map(([, count4]) => count4))
|
|
24086
24088
|
};
|
|
24087
24089
|
}
|
|
24088
24090
|
function candidateDiff(state, nextRows, plan, reusedQueryIds, mutatedQueryIds, scopedRemovalQueryIds) {
|
|
@@ -25166,7 +25168,7 @@ function normalizeCompetitorList2(domains) {
|
|
|
25166
25168
|
}
|
|
25167
25169
|
|
|
25168
25170
|
// ../api-routes/src/history.ts
|
|
25169
|
-
import { and as and21, asc as asc3, desc as desc9, eq as eq27, gte as gte5, inArray as inArray11 } from "drizzle-orm";
|
|
25171
|
+
import { and as and21, asc as asc3, count, desc as desc9, eq as eq27, gte as gte5, inArray as inArray11 } from "drizzle-orm";
|
|
25170
25172
|
|
|
25171
25173
|
// ../api-routes/src/notification-redaction.ts
|
|
25172
25174
|
var REDACTED_URL = {
|
|
@@ -25210,6 +25212,38 @@ function redactNotificationDiff(value) {
|
|
|
25210
25212
|
|
|
25211
25213
|
// ../api-routes/src/history.ts
|
|
25212
25214
|
async function historyRoutes(app) {
|
|
25215
|
+
app.post("/projects/:name/results/clear", async (request) => {
|
|
25216
|
+
requireAdminSession(request);
|
|
25217
|
+
requireScope(request, "runs.write");
|
|
25218
|
+
const project = resolveProject(app.db, request.params.name);
|
|
25219
|
+
const parsed = resultsClearRequestSchema.safeParse(request.body);
|
|
25220
|
+
if (!parsed.success) throw validationError("Invalid history cleanup request", { issues: parsed.error.issues });
|
|
25221
|
+
const input = parsed.data;
|
|
25222
|
+
return app.db.transaction((tx) => {
|
|
25223
|
+
const active = tx.select({ id: runs.id }).from(runs).where(and21(eq27(runs.projectId, project.id), eq27(runs.kind, RunKinds["answer-visibility"]), inArray11(runs.status, ["queued", "running"]))).get();
|
|
25224
|
+
const activeResearch = tx.select({ id: researchRuns.id }).from(researchRuns).where(and21(eq27(researchRuns.projectId, project.id), inArray11(researchRuns.status, ["queued", "running"]))).get();
|
|
25225
|
+
if (active || activeResearch) throw runInProgress(project.name, active ? "answer-visibility" : "research", (active ?? activeResearch).id);
|
|
25226
|
+
const selectedRuns = tx.select({ id: runs.id, kind: runs.kind }).from(runs).where(and21(eq27(runs.projectId, project.id), inArray11(runs.id, input.runIds))).all();
|
|
25227
|
+
const selectedResearch = tx.select({ id: researchRuns.id }).from(researchRuns).where(and21(eq27(researchRuns.projectId, project.id), inArray11(researchRuns.id, input.researchRunIds))).all();
|
|
25228
|
+
if (selectedRuns.length !== input.runIds.length || selectedResearch.length !== input.researchRunIds.length) throw notFound("Selected saved run in project", project.name);
|
|
25229
|
+
if (selectedRuns.some((run) => run.kind !== RunKinds["answer-visibility"])) throw validationError("Only answer-visibility runs and research batches can be cleared. Site Health and integration runs are preserved.");
|
|
25230
|
+
const result = {
|
|
25231
|
+
dryRun: !input.confirm,
|
|
25232
|
+
runIds: input.runIds,
|
|
25233
|
+
researchRunIds: input.researchRunIds,
|
|
25234
|
+
querySnapshots: tx.select({ value: count() }).from(querySnapshots).where(inArray11(querySnapshots.runId, input.runIds)).get().value,
|
|
25235
|
+
researchQueries: tx.select({ value: count() }).from(researchRunQueries).where(inArray11(researchRunQueries.researchRunId, input.researchRunIds)).get().value,
|
|
25236
|
+
insights: tx.select({ value: count() }).from(insights).where(inArray11(insights.runId, input.runIds)).get().value,
|
|
25237
|
+
healthSnapshots: tx.select({ value: count() }).from(healthSnapshots).where(inArray11(healthSnapshots.runId, input.runIds)).get().value
|
|
25238
|
+
};
|
|
25239
|
+
if (input.confirm) {
|
|
25240
|
+
tx.delete(researchRuns).where(and21(eq27(researchRuns.projectId, project.id), inArray11(researchRuns.id, input.researchRunIds))).run();
|
|
25241
|
+
tx.delete(runs).where(and21(eq27(runs.projectId, project.id), inArray11(runs.id, input.runIds))).run();
|
|
25242
|
+
writeAuditLog(tx, { projectId: project.id, actor: request.principal ? `${request.principal.kind}:${request.principal.id}` : "api", action: "results.cleared", entityType: "project", entityId: project.id, diff: result, userAgent: request.headers["user-agent"] });
|
|
25243
|
+
}
|
|
25244
|
+
return result;
|
|
25245
|
+
});
|
|
25246
|
+
});
|
|
25213
25247
|
app.get("/projects/:name/history", async (request, reply) => {
|
|
25214
25248
|
const project = resolveProject(app.db, request.params.name);
|
|
25215
25249
|
const filters = [eq27(auditLog.projectId, project.id)];
|
|
@@ -26225,10 +26259,10 @@ function computeQueryChanges(projectQueries, cutoff) {
|
|
|
26225
26259
|
}
|
|
26226
26260
|
const days = [...byDay.entries()].sort((a, b) => a[0].localeCompare(b[0]));
|
|
26227
26261
|
if (days.length <= 1) return [];
|
|
26228
|
-
return days.slice(1).map(([date,
|
|
26262
|
+
return days.slice(1).map(([date, count4]) => ({
|
|
26229
26263
|
date: (/* @__PURE__ */ new Date(date + "T00:00:00.000Z")).toISOString(),
|
|
26230
|
-
delta:
|
|
26231
|
-
label: `+${
|
|
26264
|
+
delta: count4,
|
|
26265
|
+
label: `+${count4} kp`
|
|
26232
26266
|
}));
|
|
26233
26267
|
}
|
|
26234
26268
|
function pooledRate(buckets, rateKey) {
|
|
@@ -26303,15 +26337,15 @@ function buildRankedList(domains, limit) {
|
|
|
26303
26337
|
function buildCategoryCounts(counts2) {
|
|
26304
26338
|
let grandTotal = 0;
|
|
26305
26339
|
for (const domains of counts2.values()) {
|
|
26306
|
-
for (const
|
|
26340
|
+
for (const count4 of domains.values()) grandTotal += count4;
|
|
26307
26341
|
}
|
|
26308
26342
|
const result = [];
|
|
26309
26343
|
for (const [category, domains] of counts2) {
|
|
26310
26344
|
let categoryTotal = 0;
|
|
26311
26345
|
const domainEntries = [];
|
|
26312
|
-
for (const [domain,
|
|
26313
|
-
categoryTotal +=
|
|
26314
|
-
domainEntries.push({ domain, count:
|
|
26346
|
+
for (const [domain, count4] of domains) {
|
|
26347
|
+
categoryTotal += count4;
|
|
26348
|
+
domainEntries.push({ domain, count: count4 });
|
|
26315
26349
|
}
|
|
26316
26350
|
domainEntries.sort((a, b) => b.count - a.count);
|
|
26317
26351
|
result.push({
|
|
@@ -27587,8 +27621,8 @@ function gscDateRange(report) {
|
|
|
27587
27621
|
const end = summary2?.periodEnd || gsc?.periodEnd || gsc?.trend.at(-1)?.date || "";
|
|
27588
27622
|
return formatDateRange(start, end);
|
|
27589
27623
|
}
|
|
27590
|
-
function pluralize(
|
|
27591
|
-
return
|
|
27624
|
+
function pluralize(count4, singular, plural = `${singular}s`) {
|
|
27625
|
+
return count4 === 1 ? singular : plural;
|
|
27592
27626
|
}
|
|
27593
27627
|
var PROVIDER_DISPLAY_NAMES = {
|
|
27594
27628
|
gemini: "Gemini",
|
|
@@ -29422,9 +29456,9 @@ function renderInsights(report) {
|
|
|
29422
29456
|
);
|
|
29423
29457
|
}
|
|
29424
29458
|
const haveDeduped = list.every((i) => typeof i.instanceCount === "number");
|
|
29425
|
-
const rows = (haveDeduped ? list.map((i) => ({ rep: i, count: i.instanceCount })) : groupInsights(list).map((g) => ({ rep: g.representative, count: g.count }))).map(({ rep: i, count:
|
|
29459
|
+
const rows = (haveDeduped ? list.map((i) => ({ rep: i, count: i.instanceCount })) : groupInsights(list).map((g) => ({ rep: g.representative, count: g.count }))).map(({ rep: i, count: count4 }) => {
|
|
29426
29460
|
const tone = severityTone(i.severity);
|
|
29427
|
-
const countChip =
|
|
29461
|
+
const countChip = count4 > 1 ? ` <span class="badge tone-neutral">\xD7 ${count4}</span>` : "";
|
|
29428
29462
|
return `<tr>
|
|
29429
29463
|
<td class="col-severity"><span class="badge tone-${tone}">${escapeHtml2(reportSeverityLabel(i.severity))}</span></td>
|
|
29430
29464
|
<td class="col-title">${escapeHtml2(i.title)}${countChip}</td>
|
|
@@ -30881,9 +30915,9 @@ function contentActionVerb(action) {
|
|
|
30881
30915
|
return "Add schema to";
|
|
30882
30916
|
}
|
|
30883
30917
|
}
|
|
30884
|
-
function confidenceFromEvidence(
|
|
30885
|
-
if (
|
|
30886
|
-
if (
|
|
30918
|
+
function confidenceFromEvidence(count4) {
|
|
30919
|
+
if (count4 >= 3) return "high";
|
|
30920
|
+
if (count4 >= 1) return "medium";
|
|
30887
30921
|
return "low";
|
|
30888
30922
|
}
|
|
30889
30923
|
function actionAudienceMatches2(action, audience) {
|
|
@@ -32057,9 +32091,9 @@ function summarizeVerificationHits(rows) {
|
|
|
32057
32091
|
return { counts: counts2, unsupportedRows, unsupportedHits };
|
|
32058
32092
|
}
|
|
32059
32093
|
function summarizeServer(crawlers, fetches, referrals) {
|
|
32060
|
-
const total = referrals.reduce((
|
|
32061
|
-
const paid = referrals.reduce((
|
|
32062
|
-
const organic = referrals.reduce((
|
|
32094
|
+
const total = referrals.reduce((count4, row) => count4 + row.sessionsOrHits, 0);
|
|
32095
|
+
const paid = referrals.reduce((count4, row) => count4 + row.paidSessionsOrHits, 0);
|
|
32096
|
+
const organic = referrals.reduce((count4, row) => count4 + row.organicSessionsOrHits, 0);
|
|
32063
32097
|
const crawlerHits = summarizeVerificationHits(crawlers);
|
|
32064
32098
|
const userFetchHits = summarizeVerificationHits(fetches);
|
|
32065
32099
|
return {
|
|
@@ -32208,10 +32242,10 @@ function buildOrganicEvidence(db, projectName, periodDays) {
|
|
|
32208
32242
|
const gaWindow = gaStartDate && gaEndDate ? gaRows.filter((row) => inRange(row.date, gaStartDate, gaEndDate)) : [];
|
|
32209
32243
|
const legacyGaCohorts = gaCohorts.map((cohort) => ({
|
|
32210
32244
|
...cohort,
|
|
32211
|
-
organicSessions: gaRows.filter((row) => inRange(row.date, cohort.startDate, cohort.endDate)).reduce((
|
|
32245
|
+
organicSessions: gaRows.filter((row) => inRange(row.date, cohort.startDate, cohort.endDate)).reduce((count4, row) => count4 + row.organicSessions, 0)
|
|
32212
32246
|
}));
|
|
32213
32247
|
let ga4 = gaRows.length ? {
|
|
32214
|
-
organicSessions: gaWindow.reduce((
|
|
32248
|
+
organicSessions: gaWindow.reduce((count4, row) => count4 + row.organicSessions, 0),
|
|
32215
32249
|
cohorts: legacyGaCohorts
|
|
32216
32250
|
} : null;
|
|
32217
32251
|
if (nativeAcquisitionActive && nativeAcquisition.periods.length === 0) {
|
|
@@ -32234,8 +32268,8 @@ function buildOrganicEvidence(db, projectName, periodDays) {
|
|
|
32234
32268
|
const allGaAiRows = db.select().from(gaAiReferrals).where(and30(eq35(gaAiReferrals.projectId, project.id), gte10(gaAiReferrals.date, gaStartDate ?? startDate), lte8(gaAiReferrals.date, gaEndDate ?? endDate))).all().filter((row) => row.sourceDimension === "session");
|
|
32235
32269
|
const aiRows = gaStartDate && gaEndDate ? allGaAiRows.filter((row) => inRange(row.date, gaStartDate, gaEndDate)) : [];
|
|
32236
32270
|
const gaAiReferralSummary = allGaAiRows.length ? {
|
|
32237
|
-
paidSessions: aiRows.filter((row) => row.trafficClass === AiReferralTrafficClasses.paid).reduce((
|
|
32238
|
-
organicSessions: aiRows.filter((row) => row.trafficClass === AiReferralTrafficClasses.organic).reduce((
|
|
32271
|
+
paidSessions: aiRows.filter((row) => row.trafficClass === AiReferralTrafficClasses.paid).reduce((count4, row) => count4 + row.sessions, 0),
|
|
32272
|
+
organicSessions: aiRows.filter((row) => row.trafficClass === AiReferralTrafficClasses.organic).reduce((count4, row) => count4 + row.sessions, 0)
|
|
32239
32273
|
} : null;
|
|
32240
32274
|
const serverSources = db.select().from(trafficSources).where(eq35(trafficSources.projectId, project.id)).all();
|
|
32241
32275
|
const serverStart = `${startDate}T00:00:00`;
|
|
@@ -34279,6 +34313,8 @@ var SCHEMA_TABLE = {
|
|
|
34279
34313
|
ResearchRunCreate: researchRunCreateSchema,
|
|
34280
34314
|
ResearchRunDetailDto: researchRunDetailSchema,
|
|
34281
34315
|
ResearchRunListDto: researchRunListSchema,
|
|
34316
|
+
ResultsClearRequest: resultsClearRequestSchema,
|
|
34317
|
+
ResultsClearResponse: resultsClearResponseSchema,
|
|
34282
34318
|
DoctorReportDto: doctorReportSchema,
|
|
34283
34319
|
GA4AiReferralDailyDto: ga4AiReferralDailyDtoSchema,
|
|
34284
34320
|
GA4AiReferralHistoryEntry: ga4AiReferralHistoryEntrySchema,
|
|
@@ -35995,6 +36031,16 @@ var routeCatalog = [
|
|
|
35995
36031
|
requestBody: { required: true, content: { "application/json": { schema: { $ref: "#/components/schemas/QueryTrackingCommitRequest" } } } },
|
|
35996
36032
|
responses: { 200: jsonResponse("Actual committed revision, or unchanged no-op.", "QueryTrackingCommitResponse"), 400: errorResponse("Invalid mutation or review token."), 403: errorResponse("Write access required."), 404: errorResponse("Project or source not found."), 409: errorResponse("Workspace changed or a sweep is using the live query catalog.") }
|
|
35997
36033
|
},
|
|
36034
|
+
{
|
|
36035
|
+
method: "post",
|
|
36036
|
+
path: "/api/v1/projects/{name}/results/clear",
|
|
36037
|
+
summary: "Preview or clear selected saved visibility and research results",
|
|
36038
|
+
tags: ["runs"],
|
|
36039
|
+
description: "Administrator or runs.write key only. Exact run IDs are required; confirm defaults to false for a non-mutating preview. Refuses active visibility or research work and any selected non-visibility run. Keeps queries, measurement plans, Site Health, backlinks, schedules, audit history, and usage accounting. Back up stored evidence before confirming deletion.",
|
|
36040
|
+
parameters: [nameParameter],
|
|
36041
|
+
requestBody: { required: true, content: { "application/json": { schema: { $ref: "#/components/schemas/ResultsClearRequest" } } } },
|
|
36042
|
+
responses: { 200: jsonResponse("Selected history previewed or cleared.", "ResultsClearResponse"), 400: errorResponse("Invalid selection or unsupported run kind."), 403: errorResponse("Administrator or runs.write scope required."), 404: errorResponse("Project or selected run not found."), 409: errorResponse("Visibility or research work is active.") }
|
|
36043
|
+
},
|
|
35998
36044
|
{
|
|
35999
36045
|
method: "get",
|
|
36000
36046
|
path: "/api/v1/projects/{name}/research/runs",
|
|
@@ -44426,12 +44472,12 @@ async function getLodging(accessToken, locationName, opts = {}) {
|
|
|
44426
44472
|
}
|
|
44427
44473
|
}
|
|
44428
44474
|
function countPopulatedGroups(lodging) {
|
|
44429
|
-
let
|
|
44475
|
+
let count4 = 0;
|
|
44430
44476
|
for (const [key, value] of Object.entries(lodging)) {
|
|
44431
44477
|
if (key === "name" || key === "metadata") continue;
|
|
44432
|
-
if (isPopulated(value))
|
|
44478
|
+
if (isPopulated(value)) count4++;
|
|
44433
44479
|
}
|
|
44434
|
-
return
|
|
44480
|
+
return count4;
|
|
44435
44481
|
}
|
|
44436
44482
|
function isPopulated(value) {
|
|
44437
44483
|
if (value === null || value === void 0) return false;
|
|
@@ -49475,7 +49521,7 @@ function createActivationStore(app, request) {
|
|
|
49475
49521
|
function countManifest(manifest) {
|
|
49476
49522
|
return {
|
|
49477
49523
|
adGroupCount: manifest.campaign.adGroups.length,
|
|
49478
|
-
adCount: manifest.campaign.adGroups.reduce((
|
|
49524
|
+
adCount: manifest.campaign.adGroups.reduce((count4, group) => count4 + group.ads.length, 0)
|
|
49479
49525
|
};
|
|
49480
49526
|
}
|
|
49481
49527
|
function resolveAdsActivationMaxEntities(env = process.env) {
|
|
@@ -80975,7 +81021,7 @@ function dedupeStrings(input) {
|
|
|
80975
81021
|
|
|
80976
81022
|
// ../api-routes/src/technical-aeo.ts
|
|
80977
81023
|
import crypto48 from "crypto";
|
|
80978
|
-
import { and as and53, asc as asc11, count, desc as desc27, eq as eq64, inArray as inArray24, isNotNull as isNotNull5, isNull as isNull11, lt as lt10, or as or13, sql as sql24 } from "drizzle-orm";
|
|
81024
|
+
import { and as and53, asc as asc11, count as count2, desc as desc27, eq as eq64, inArray as inArray24, isNotNull as isNotNull5, isNull as isNull11, lt as lt10, or as or13, sql as sql24 } from "drizzle-orm";
|
|
80979
81025
|
import { alias } from "drizzle-orm/sqlite-core";
|
|
80980
81026
|
var FETCHED_SITE_CRAWL_STATES = /* @__PURE__ */ new Set([
|
|
80981
81027
|
...SiteCrawlFetchedStates,
|
|
@@ -81416,7 +81462,7 @@ async function technicalAeoRoutes(app, opts) {
|
|
|
81416
81462
|
const conds = [eq64(siteAuditPages.projectId, project.id), eq64(siteAuditPages.runId, latest.runId)];
|
|
81417
81463
|
if (statusFilter) conds.push(eq64(siteAuditPages.status, statusFilter));
|
|
81418
81464
|
const where = and53(...conds);
|
|
81419
|
-
const totalRow = app.db.select({ value:
|
|
81465
|
+
const totalRow = app.db.select({ value: count2() }).from(siteAuditPages).where(where).get();
|
|
81420
81466
|
const total = totalRow?.value ?? 0;
|
|
81421
81467
|
const limit = parsePositiveInt(request.query.limit, 100, 500);
|
|
81422
81468
|
const offset = parsePositiveInt(request.query.offset, 0, Number.MAX_SAFE_INTEGER);
|
|
@@ -82403,7 +82449,7 @@ async function technicalAeoRoutes(app, opts) {
|
|
|
82403
82449
|
};
|
|
82404
82450
|
}
|
|
82405
82451
|
const where = and53(...filters);
|
|
82406
|
-
const total = app.db.select({ value:
|
|
82452
|
+
const total = app.db.select({ value: count2() }).from(siteCrawlPages).where(where).get()?.value ?? 0;
|
|
82407
82453
|
const rows = app.db.select().from(siteCrawlPages).where(where).orderBy(...orderBy).limit(limit).offset(offset).all();
|
|
82408
82454
|
const nextOffset = offset + rows.length;
|
|
82409
82455
|
return {
|
|
@@ -82526,7 +82572,7 @@ async function technicalAeoRoutes(app, opts) {
|
|
|
82526
82572
|
const followable = parseBoolean2(request.query.followable);
|
|
82527
82573
|
if (followable != null) filters.push(eq64(siteCrawlEdges.followable, followable));
|
|
82528
82574
|
const where = and53(...filters);
|
|
82529
|
-
const total = app.db.select({ value:
|
|
82575
|
+
const total = app.db.select({ value: count2() }).from(siteCrawlEdges).where(where).get()?.value ?? 0;
|
|
82530
82576
|
const limit = parseBoundedLimit(request.query.limit, 100, 200);
|
|
82531
82577
|
const offset = decodeCursor(request.query.cursor);
|
|
82532
82578
|
const rows = app.db.select().from(siteCrawlEdges).where(where).orderBy(asc11(siteCrawlEdges.edgeKey)).limit(limit).offset(offset).all();
|
|
@@ -82642,7 +82688,7 @@ async function technicalAeoRoutes(app, opts) {
|
|
|
82642
82688
|
// promise a page the list cannot fill.
|
|
82643
82689
|
isNotNull5(sql24`json_extract(${siteCrawlFindings.evidence}, '$.statusCode')`)
|
|
82644
82690
|
);
|
|
82645
|
-
const total = app.db.select({ value:
|
|
82691
|
+
const total = app.db.select({ value: count2() }).from(siteCrawlFindings).where(where).get()?.value ?? 0;
|
|
82646
82692
|
const limit = parseBoundedLimit(request.query.limit, 100, 200);
|
|
82647
82693
|
const offset = decodeCursor(request.query.cursor);
|
|
82648
82694
|
const rows = app.db.select().from(siteCrawlFindings).where(where).orderBy(asc11(siteCrawlFindings.findingKey)).limit(limit).offset(offset).all();
|
|
@@ -82780,7 +82826,7 @@ async function technicalAeoRoutes(app, opts) {
|
|
|
82780
82826
|
eq64(siteCrawlPages.attemptId, attempt.id),
|
|
82781
82827
|
eq64(siteCrawlPages.auditState, "success")
|
|
82782
82828
|
);
|
|
82783
|
-
const pagesAudited = tx.select({ value:
|
|
82829
|
+
const pagesAudited = tx.select({ value: count2() }).from(siteCrawlPages).where(auditedWhere).get()?.value ?? 0;
|
|
82784
82830
|
if (state !== "collecting") {
|
|
82785
82831
|
return { ...base, pagesAudited, examples: [] };
|
|
82786
82832
|
}
|
|
@@ -82884,7 +82930,7 @@ async function technicalAeoRoutes(app, opts) {
|
|
|
82884
82930
|
|
|
82885
82931
|
// ../api-routes/src/research.ts
|
|
82886
82932
|
import crypto49 from "crypto";
|
|
82887
|
-
import { and as and54, count as
|
|
82933
|
+
import { and as and54, count as count3, desc as desc28, eq as eq65, gte as gte17, lt as lt11, sql as sql25 } from "drizzle-orm";
|
|
82888
82934
|
var sameLocation = (a, b) => a.label === b.label && a.city === b.city && a.region === b.region && a.country === b.country && a.timezone === b.timezone;
|
|
82889
82935
|
async function researchRoutes(app, opts) {
|
|
82890
82936
|
const viewerDailyRunLimit = opts.viewerDailyRunLimit ?? DEFAULT_VIEWER_RESEARCH_DAILY_RUN_LIMIT;
|
|
@@ -82930,7 +82976,7 @@ async function researchRoutes(app, opts) {
|
|
|
82930
82976
|
}
|
|
82931
82977
|
if (initiatedBy?.kind === "user" && initiatedBy.role === UserRoles.viewer) {
|
|
82932
82978
|
const { start, end, date } = utcDayBounds(now);
|
|
82933
|
-
const used = tx.select({ value:
|
|
82979
|
+
const used = tx.select({ value: count3() }).from(researchRuns).where(and54(
|
|
82934
82980
|
eq65(researchRuns.projectId, project.id),
|
|
82935
82981
|
gte17(researchRuns.createdAt, start),
|
|
82936
82982
|
lt11(researchRuns.createdAt, end),
|
|
@@ -82956,7 +83002,15 @@ async function researchRoutes(app, opts) {
|
|
|
82956
83002
|
const requested = Number.parseInt(request.query.limit ?? "", 10);
|
|
82957
83003
|
const limit = Number.isInteger(requested) && requested > 0 ? Math.min(requested, 100) : 20;
|
|
82958
83004
|
const runs2 = app.db.select().from(researchRuns).where(eq65(researchRuns.projectId, project.id)).orderBy(desc28(researchRuns.createdAt)).limit(limit).all().map(serializeRun);
|
|
82959
|
-
|
|
83005
|
+
const configured = new Set(opts.configuredProviderNames ?? []);
|
|
83006
|
+
const providers = (opts.providerAdapters ?? []).filter((adapter) => adapter.mode === "api" && !isBrowserProvider(adapter.name) && configured.has(adapter.name)).map((adapter) => ({
|
|
83007
|
+
name: adapter.name,
|
|
83008
|
+
displayName: adapter.displayName,
|
|
83009
|
+
modelConfigurable: adapter.modelConfigurable,
|
|
83010
|
+
defaultModel: project.providerModels[adapter.name] || adapter.defaultModel,
|
|
83011
|
+
knownModels: adapter.knownModels.map((model) => ({ id: model.id, displayName: model.displayName }))
|
|
83012
|
+
}));
|
|
83013
|
+
return { runs: runs2, providers };
|
|
82960
83014
|
});
|
|
82961
83015
|
app.get("/projects/:name/research/runs/:runId", async (request) => {
|
|
82962
83016
|
const project = resolveProject(app.db, request.params.name);
|
|
@@ -13158,6 +13158,23 @@ var resultsExportDtoSchema = z41.object({
|
|
|
13158
13158
|
recordCount: z41.number().int().nonnegative(),
|
|
13159
13159
|
records: z41.array(resultsExportRecordSchema)
|
|
13160
13160
|
});
|
|
13161
|
+
var resultsClearRequestSchema = z41.object({
|
|
13162
|
+
runIds: z41.array(z41.string().trim().min(1)).max(100).default([]),
|
|
13163
|
+
researchRunIds: z41.array(z41.string().trim().min(1)).max(100).default([]),
|
|
13164
|
+
confirm: z41.boolean().default(false)
|
|
13165
|
+
}).strict().superRefine((value, ctx) => {
|
|
13166
|
+
if (value.runIds.length + value.researchRunIds.length === 0) ctx.addIssue({ code: "custom", message: "Select at least one saved run." });
|
|
13167
|
+
if (new Set(value.runIds).size !== value.runIds.length || new Set(value.researchRunIds).size !== value.researchRunIds.length) ctx.addIssue({ code: "custom", message: "Run IDs must be unique." });
|
|
13168
|
+
});
|
|
13169
|
+
var resultsClearResponseSchema = z41.object({
|
|
13170
|
+
dryRun: z41.boolean(),
|
|
13171
|
+
runIds: z41.array(z41.string()),
|
|
13172
|
+
researchRunIds: z41.array(z41.string()),
|
|
13173
|
+
querySnapshots: z41.number().int().nonnegative(),
|
|
13174
|
+
researchQueries: z41.number().int().nonnegative(),
|
|
13175
|
+
insights: z41.number().int().nonnegative(),
|
|
13176
|
+
healthSnapshots: z41.number().int().nonnegative()
|
|
13177
|
+
});
|
|
13161
13178
|
|
|
13162
13179
|
// ../contracts/src/ga.ts
|
|
13163
13180
|
import { z as z43 } from "zod";
|
|
@@ -16185,7 +16202,17 @@ var researchRunQuerySchema = z56.object({
|
|
|
16185
16202
|
createdAt: z56.string()
|
|
16186
16203
|
});
|
|
16187
16204
|
var researchRunDetailSchema = researchRunSummarySchema.extend({ queries: z56.array(researchRunQuerySchema) });
|
|
16188
|
-
var
|
|
16205
|
+
var researchProviderOptionSchema = z56.object({
|
|
16206
|
+
name: z56.string(),
|
|
16207
|
+
displayName: z56.string(),
|
|
16208
|
+
modelConfigurable: z56.boolean(),
|
|
16209
|
+
defaultModel: z56.string(),
|
|
16210
|
+
knownModels: z56.array(z56.object({ id: z56.string(), displayName: z56.string() }))
|
|
16211
|
+
});
|
|
16212
|
+
var researchRunListSchema = z56.object({
|
|
16213
|
+
runs: z56.array(researchRunSummarySchema),
|
|
16214
|
+
providers: z56.array(researchProviderOptionSchema).optional()
|
|
16215
|
+
});
|
|
16189
16216
|
|
|
16190
16217
|
// ../contracts/src/ads.ts
|
|
16191
16218
|
import { z as z57 } from "zod";
|
|
@@ -17938,6 +17965,8 @@ export {
|
|
|
17938
17965
|
visibilityCompareDtoSchema,
|
|
17939
17966
|
calendarMonthBounds,
|
|
17940
17967
|
resultsExportDtoSchema,
|
|
17968
|
+
resultsClearRequestSchema,
|
|
17969
|
+
resultsClearResponseSchema,
|
|
17941
17970
|
AiReferralTrafficClasses,
|
|
17942
17971
|
classifyAiReferralTrafficClass,
|
|
17943
17972
|
aiReferralClassCounts,
|
|
@@ -88,6 +88,7 @@ import {
|
|
|
88
88
|
queryTrackingPreviewRequestSchema,
|
|
89
89
|
reportPeriodSchema,
|
|
90
90
|
researchRunCreateSchema,
|
|
91
|
+
resultsClearRequestSchema,
|
|
91
92
|
runTriggerRequestSchema,
|
|
92
93
|
schedulableRunKindSchema,
|
|
93
94
|
scheduleUpsertRequestSchema,
|
|
@@ -98,7 +99,7 @@ import {
|
|
|
98
99
|
trafficEventKindSchema,
|
|
99
100
|
trafficSeriesGranularitySchema,
|
|
100
101
|
visibilityReportRequestSchema
|
|
101
|
-
} from "./chunk-
|
|
102
|
+
} from "./chunk-HIIOVQSH.js";
|
|
102
103
|
|
|
103
104
|
// src/cli-error.ts
|
|
104
105
|
function isMachineFormat(format) {
|
|
@@ -2342,6 +2343,22 @@ var postApiV1ProjectsByNameQueryTrackingCommit = (options) => {
|
|
|
2342
2343
|
}
|
|
2343
2344
|
});
|
|
2344
2345
|
};
|
|
2346
|
+
var postApiV1ProjectsByNameResultsClear = (options) => {
|
|
2347
|
+
return (options.client ?? client).post({
|
|
2348
|
+
security: [
|
|
2349
|
+
{
|
|
2350
|
+
scheme: "bearer",
|
|
2351
|
+
type: "http"
|
|
2352
|
+
}
|
|
2353
|
+
],
|
|
2354
|
+
url: "/api/v1/projects/{name}/results/clear",
|
|
2355
|
+
...options,
|
|
2356
|
+
headers: {
|
|
2357
|
+
"Content-Type": "application/json",
|
|
2358
|
+
...options.headers
|
|
2359
|
+
}
|
|
2360
|
+
});
|
|
2361
|
+
};
|
|
2345
2362
|
var getApiV1ProjectsByNameResearchRunsByRunId = (options) => {
|
|
2346
2363
|
return (options.client ?? client).get({
|
|
2347
2364
|
security: [
|
|
@@ -8028,6 +8045,14 @@ var ApiClient = class {
|
|
|
8028
8045
|
);
|
|
8029
8046
|
}
|
|
8030
8047
|
// ── Research query runs ────────────────────────────────────────────────
|
|
8048
|
+
/** Preview or clear exact saved visibility/research run IDs. */
|
|
8049
|
+
async clearResults(project, request) {
|
|
8050
|
+
return this.invoke(() => postApiV1ProjectsByNameResultsClear({
|
|
8051
|
+
client: this.heyClient,
|
|
8052
|
+
path: { name: project },
|
|
8053
|
+
body: request
|
|
8054
|
+
}));
|
|
8055
|
+
}
|
|
8031
8056
|
/**
|
|
8032
8057
|
* Start one saved research batch. Research results are deliberately kept
|
|
8033
8058
|
* outside the tracked-query basket and visibility-run history.
|
|
@@ -9866,6 +9891,17 @@ var canonryMcpTools = [
|
|
|
9866
9891
|
openApiOperations: ["GET /api/v1/projects/{name}/export"],
|
|
9867
9892
|
handler: (client2, input) => client2.getExport(input.project)
|
|
9868
9893
|
}),
|
|
9894
|
+
defineTool({
|
|
9895
|
+
name: "canonry_results_clear",
|
|
9896
|
+
title: "Preview or clear saved results",
|
|
9897
|
+
description: "Clear only explicitly selected visibility runs and research batches. Preview is the default; back up evidence and set confirm=true to delete. Refuses active work and other run kinds. Preserves queries, plans, schedules, Site Health, backlinks, usage, and the audit trail.",
|
|
9898
|
+
access: "write",
|
|
9899
|
+
tier: "monitoring",
|
|
9900
|
+
inputSchema: resultsClearRequestSchema.safeExtend({ project: projectNameSchema }),
|
|
9901
|
+
annotations: writeAnnotations({ idempotentHint: false, destructiveHint: true }),
|
|
9902
|
+
openApiOperations: ["POST /api/v1/projects/{name}/results/clear"],
|
|
9903
|
+
handler: (client2, input) => client2.clearResults(input.project, { runIds: input.runIds, researchRunIds: input.researchRunIds, confirm: input.confirm })
|
|
9904
|
+
}),
|
|
9869
9905
|
defineTool({
|
|
9870
9906
|
name: "canonry_project_history",
|
|
9871
9907
|
title: "Get project history",
|