@canonry/canonry 6.2.0 → 6.3.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 +12 -0
- package/assets/assets/{AuditHistoryPanel-CuEMfkaA.js → AuditHistoryPanel-BUYWIjlG.js} +1 -1
- package/assets/assets/{BacklinksPage-CftadZ1-.js → BacklinksPage-aBcxpN_9.js} +1 -1
- package/assets/assets/{HistoryPage-DouRgshN.js → HistoryPage-PoBuxiY_.js} +1 -1
- package/assets/assets/{MeasurementPropertyPage-qfqv2qs9.js → MeasurementPropertyPage-DyjyqHac.js} +1 -1
- package/assets/assets/{ProjectPage-DqEVwe4t.js → ProjectPage-Mmv5YW-K.js} +1 -1
- package/assets/assets/{RunsPage-CUkMs0gB.js → RunsPage-CHHxOpzo.js} +1 -1
- package/assets/assets/{SettingsPage-LLQ40tSh.js → SettingsPage-CNKnrLXC.js} +1 -1
- package/assets/assets/{SiteHealthSection-Ba7foDiU.js → SiteHealthSection-C9RivT7G.js} +3 -3
- package/assets/assets/{TrafficPage-Cu_ZR3--.js → TrafficPage-CY-ibXnb.js} +1 -1
- package/assets/assets/{TrafficSourceDetailPage-NKZq7jf9.js → TrafficSourceDetailPage-BgiPXubs.js} +1 -1
- package/assets/assets/{extract-error-message-BdQYrz9N.js → extract-error-message-H1dzzfBP.js} +1 -1
- package/assets/assets/{index-HOeLz1ZL.js → index-DSCun3I9.js} +21 -21
- package/assets/assets/{react-sigma_core.esm.min-CZaoE5cU.js → react-sigma_core.esm.min-uiYtR_DU.js} +1 -1
- package/assets/assets/{v2-overview-adapter-BVx4nI49.js → v2-overview-adapter-BQokN2eb.js} +1 -1
- package/assets/index.html +1 -1
- package/dist/{chunk-Y2B7JRSB.js → chunk-5GY5WBAF.js} +3 -3
- package/dist/{chunk-W3GDZZNF.js → chunk-DERWXLHX.js} +15 -1
- package/dist/{chunk-6EPN4XY5.js → chunk-EV5G5QRR.js} +324 -280
- package/dist/{chunk-4EKOKWQT.js → chunk-FSRVG2H7.js} +2 -2
- package/dist/{chunk-2RFHQ6XT.js → chunk-OTROA7CN.js} +199 -106
- package/dist/{chunk-ENI3GOWW.js → chunk-QVGG76UW.js} +78 -24
- package/dist/{chunk-V6JUBTNL.js → chunk-ZZEPF3A5.js} +23 -3
- package/dist/cli.js +53 -8
- package/dist/{demo-server-CH7MOBXW.js → demo-server-5MNLI6GC.js} +4 -4
- package/dist/index.js +6 -6
- package/dist/{intelligence-service-4IONMOFB.js → intelligence-service-5J36RBEM.js} +2 -2
- package/dist/mcp.js +4 -4
- package/package.json +11 -11
|
@@ -19,21 +19,21 @@ import {
|
|
|
19
19
|
runWithUsageTags,
|
|
20
20
|
saveConfigPatch,
|
|
21
21
|
sentimentInstallReadiness
|
|
22
|
-
} from "./chunk-
|
|
22
|
+
} from "./chunk-ZZEPF3A5.js";
|
|
23
23
|
import {
|
|
24
24
|
computeFactorAverages,
|
|
25
25
|
deleteSiteCrawlGraphLayout,
|
|
26
26
|
persistSiteCrawlGraphLayout,
|
|
27
27
|
prepareSiteCrawlGraphLayout,
|
|
28
28
|
recordedSharePct
|
|
29
|
-
} from "./chunk-
|
|
29
|
+
} from "./chunk-FSRVG2H7.js";
|
|
30
30
|
import {
|
|
31
31
|
CanonryMcpToolNames,
|
|
32
32
|
CliError,
|
|
33
33
|
PACKAGE_VERSION,
|
|
34
34
|
canonryMcpTools,
|
|
35
35
|
isMachineFormat
|
|
36
|
-
} from "./chunk-
|
|
36
|
+
} from "./chunk-DERWXLHX.js";
|
|
37
37
|
import {
|
|
38
38
|
CC_CACHE_DIR,
|
|
39
39
|
DUCKDB_SPEC,
|
|
@@ -214,7 +214,7 @@ import {
|
|
|
214
214
|
siteLivenessState,
|
|
215
215
|
toAlertView,
|
|
216
216
|
usageCounters
|
|
217
|
-
} from "./chunk-
|
|
217
|
+
} from "./chunk-QVGG76UW.js";
|
|
218
218
|
import {
|
|
219
219
|
AGENT_MEMORY_VALUE_MAX_BYTES,
|
|
220
220
|
AGENT_NONE,
|
|
@@ -232,6 +232,7 @@ import {
|
|
|
232
232
|
CheckNotificationPolicies,
|
|
233
233
|
DEFAULT_VIEWER_RESEARCH_DAILY_RUN_LIMIT,
|
|
234
234
|
DiscoveryCompetitorTypes,
|
|
235
|
+
FEEDBACK_LIMITS,
|
|
235
236
|
GOOGLE_ADS_CAMPAIGN_METRICS_MAX_CAMPAIGNS,
|
|
236
237
|
GOOGLE_ADS_CAMPAIGN_METRICS_MAX_DAYS,
|
|
237
238
|
GOOGLE_ADS_CAMPAIGN_METRICS_MAX_ROWS,
|
|
@@ -316,6 +317,7 @@ import {
|
|
|
316
317
|
contentBriefDtoSchema,
|
|
317
318
|
createTemplateLinkDetectionTally,
|
|
318
319
|
createTemplateLinkPairIndex,
|
|
320
|
+
deliveryFailed,
|
|
319
321
|
deriveCitedUrlCandidates,
|
|
320
322
|
deriveGoogleAdsEffectiveGoalGraph,
|
|
321
323
|
deriveIndexCoverage,
|
|
@@ -385,7 +387,9 @@ import {
|
|
|
385
387
|
percentOf,
|
|
386
388
|
providerError,
|
|
387
389
|
providerSupportsLocationContext,
|
|
390
|
+
quotaExceeded,
|
|
388
391
|
ratioUnitSchema,
|
|
392
|
+
redactFeedbackText,
|
|
389
393
|
registrableDomain,
|
|
390
394
|
reportMonthsForDoctor,
|
|
391
395
|
resolveNegativeReviewMaxStars,
|
|
@@ -416,7 +420,7 @@ import {
|
|
|
416
420
|
visibilityReportRequestSchema,
|
|
417
421
|
winnabilityClassLabel,
|
|
418
422
|
withRetry
|
|
419
|
-
} from "./chunk-
|
|
423
|
+
} from "./chunk-EV5G5QRR.js";
|
|
420
424
|
|
|
421
425
|
// src/runtime-context.ts
|
|
422
426
|
function cliRuntimeContext(env = process.env, stdio = process) {
|
|
@@ -3631,7 +3635,7 @@ function createGoogleMarketingRuntime(options) {
|
|
|
3631
3635
|
|
|
3632
3636
|
// src/server.ts
|
|
3633
3637
|
import { createRequire as createRequire3 } from "module";
|
|
3634
|
-
import
|
|
3638
|
+
import crypto29 from "crypto";
|
|
3635
3639
|
import fs9 from "fs";
|
|
3636
3640
|
import path8 from "path";
|
|
3637
3641
|
import { fileURLToPath as fileURLToPath3 } from "url";
|
|
@@ -7854,13 +7858,101 @@ function createApiUsageTelemetry(options = {}) {
|
|
|
7854
7858
|
};
|
|
7855
7859
|
}
|
|
7856
7860
|
|
|
7861
|
+
// src/feedback.ts
|
|
7862
|
+
import crypto4 from "crypto";
|
|
7863
|
+
var FEEDBACK_ENDPOINT = "https://canonry.ai/api/feedback";
|
|
7864
|
+
var TIMEOUT_MS2 = 1e4;
|
|
7865
|
+
var FEEDBACK_MAX_BODY_BYTES = 8e3;
|
|
7866
|
+
function feedbackSource(context) {
|
|
7867
|
+
const surface = classifyUsageSurface({
|
|
7868
|
+
userAgent: context.userAgent,
|
|
7869
|
+
usageLabels: { surface: context.surface }
|
|
7870
|
+
});
|
|
7871
|
+
if (surface === "cli" || surface === "dashboard") return surface;
|
|
7872
|
+
if (surface === "mcp-stdio" || surface === "mcp-http") return "mcp";
|
|
7873
|
+
return "api";
|
|
7874
|
+
}
|
|
7875
|
+
async function sendFeedback(submission, context, deps = {}) {
|
|
7876
|
+
const doFetch = deps.fetch ?? fetch;
|
|
7877
|
+
const telemetryOn = (deps.telemetryEnabled ?? isTelemetryEnabled)();
|
|
7878
|
+
const anonymousId = telemetryOn ? (deps.anonymousId ?? getOrCreateAnonymousId)() : void 0;
|
|
7879
|
+
const agent = [context.agent, context.mcpClient].map((label) => normalizeAgentSlug(label)).find((slug) => !!slug && slug !== "none");
|
|
7880
|
+
const payload = {
|
|
7881
|
+
feedbackId: crypto4.randomUUID(),
|
|
7882
|
+
...anonymousId ? { anonymousId } : {},
|
|
7883
|
+
kind: submission.kind,
|
|
7884
|
+
summary: redactFeedbackText(submission.summary, FEEDBACK_LIMITS.summary),
|
|
7885
|
+
...submission.details ? { details: redactFeedbackText(submission.details, FEEDBACK_LIMITS.details) } : {},
|
|
7886
|
+
...submission.area ? { area: redactFeedbackText(submission.area, FEEDBACK_LIMITS.area) } : {},
|
|
7887
|
+
...submission.command ? { command: redactFeedbackText(submission.command, FEEDBACK_LIMITS.command) } : {},
|
|
7888
|
+
...submission.errorCode ? { errorCode: redactFeedbackText(submission.errorCode, FEEDBACK_LIMITS.errorCode) } : {},
|
|
7889
|
+
source: feedbackSource(context),
|
|
7890
|
+
...agent ? { agent } : {},
|
|
7891
|
+
version: PACKAGE_VERSION.slice(0, 20),
|
|
7892
|
+
nodeVersion: process.versions.node.slice(0, 20),
|
|
7893
|
+
os: process.platform.slice(0, 20),
|
|
7894
|
+
arch: process.arch.slice(0, 20),
|
|
7895
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
7896
|
+
};
|
|
7897
|
+
const body = fitToByteBudget(payload);
|
|
7898
|
+
let response;
|
|
7899
|
+
try {
|
|
7900
|
+
response = await doFetch(FEEDBACK_ENDPOINT, {
|
|
7901
|
+
method: "POST",
|
|
7902
|
+
headers: { "Content-Type": "application/json" },
|
|
7903
|
+
body,
|
|
7904
|
+
signal: AbortSignal.timeout(TIMEOUT_MS2)
|
|
7905
|
+
});
|
|
7906
|
+
} catch {
|
|
7907
|
+
throw deliveryFailed("Could not reach canonry.ai to send feedback. Check the network and try again.");
|
|
7908
|
+
}
|
|
7909
|
+
if (response.status === 202 || response.ok) {
|
|
7910
|
+
const body2 = await response.json().catch(() => ({}));
|
|
7911
|
+
return { accepted: body2.accepted ?? true, id: typeof body2.id === "string" ? body2.id : payload.feedbackId };
|
|
7912
|
+
}
|
|
7913
|
+
if (response.status === 429) throw quotaExceeded("feedback submissions", { retryLater: true });
|
|
7914
|
+
if (response.status === 400 || response.status === 413) {
|
|
7915
|
+
const body2 = await response.json().catch(() => ({}));
|
|
7916
|
+
throw validationError("canonry.ai rejected the feedback", body2.issues ? { issues: body2.issues } : void 0);
|
|
7917
|
+
}
|
|
7918
|
+
throw deliveryFailed(`canonry.ai could not store the feedback (HTTP ${response.status}). Try again later.`);
|
|
7919
|
+
}
|
|
7920
|
+
function truncateCodePoints(value, maxCodePoints) {
|
|
7921
|
+
return Array.from(value).slice(0, Math.max(0, maxCodePoints)).join("");
|
|
7922
|
+
}
|
|
7923
|
+
function fitToByteBudget(payload) {
|
|
7924
|
+
let current = { ...payload };
|
|
7925
|
+
for (const field of ["details", "summary"]) {
|
|
7926
|
+
let serialized = JSON.stringify(current);
|
|
7927
|
+
let bytes = Buffer.byteLength(serialized, "utf8");
|
|
7928
|
+
while (bytes > FEEDBACK_MAX_BODY_BYTES) {
|
|
7929
|
+
const text = current[field];
|
|
7930
|
+
if (typeof text !== "string" || text.length === 0) break;
|
|
7931
|
+
const points = Array.from(text).length;
|
|
7932
|
+
const target = points - Math.max(1, Math.ceil((bytes - FEEDBACK_MAX_BODY_BYTES) / 4));
|
|
7933
|
+
if (field === "summary" && target < 1) break;
|
|
7934
|
+
const shorter = truncateCodePoints(text, target);
|
|
7935
|
+
if (field === "details" && shorter.length === 0) {
|
|
7936
|
+
const { details: _dropped, ...rest } = current;
|
|
7937
|
+
current = rest;
|
|
7938
|
+
} else {
|
|
7939
|
+
current = { ...current, [field]: shorter };
|
|
7940
|
+
}
|
|
7941
|
+
serialized = JSON.stringify(current);
|
|
7942
|
+
bytes = Buffer.byteLength(serialized, "utf8");
|
|
7943
|
+
}
|
|
7944
|
+
if (bytes <= FEEDBACK_MAX_BODY_BYTES) return serialized;
|
|
7945
|
+
}
|
|
7946
|
+
return JSON.stringify(current);
|
|
7947
|
+
}
|
|
7948
|
+
|
|
7857
7949
|
// src/instance-identity.ts
|
|
7858
7950
|
function nonBlank(value) {
|
|
7859
7951
|
const trimmed = value?.trim();
|
|
7860
7952
|
return trimmed ? trimmed : void 0;
|
|
7861
7953
|
}
|
|
7862
7954
|
function resolveBuildCommit(env = process.env) {
|
|
7863
|
-
const embedded = true ? "
|
|
7955
|
+
const embedded = true ? "a0351a3c7ac5eb8e0e4028ee004ddd5a12874575" : void 0;
|
|
7864
7956
|
return nonBlank(embedded) ?? nonBlank(env.CANONRY_COMMIT);
|
|
7865
7957
|
}
|
|
7866
7958
|
function resolveInstanceIdentity(env = process.env) {
|
|
@@ -7871,7 +7963,7 @@ function resolveInstanceIdentity(env = process.env) {
|
|
|
7871
7963
|
}
|
|
7872
7964
|
|
|
7873
7965
|
// src/job-runner.ts
|
|
7874
|
-
import
|
|
7966
|
+
import crypto7 from "crypto";
|
|
7875
7967
|
import fs4 from "fs";
|
|
7876
7968
|
import path3 from "path";
|
|
7877
7969
|
import os3 from "os";
|
|
@@ -7879,7 +7971,7 @@ import { setImmediate as yieldToEventLoop } from "timers/promises";
|
|
|
7879
7971
|
import { and as and3, asc as asc2, count, desc, eq as eq3, inArray, isNotNull, isNull, lt, ne, sql as sql2 } from "drizzle-orm";
|
|
7880
7972
|
|
|
7881
7973
|
// src/run-telemetry.ts
|
|
7882
|
-
import
|
|
7974
|
+
import crypto5 from "crypto";
|
|
7883
7975
|
function extractRegistrableHost(input) {
|
|
7884
7976
|
if (!input) return null;
|
|
7885
7977
|
const trimmed = input.trim();
|
|
@@ -7899,7 +7991,7 @@ function extractRegistrableHost(input) {
|
|
|
7899
7991
|
function hashDomain(input) {
|
|
7900
7992
|
const host = extractRegistrableHost(input);
|
|
7901
7993
|
if (!host) return null;
|
|
7902
|
-
return
|
|
7994
|
+
return crypto5.createHash("sha256").update(host).digest("hex");
|
|
7903
7995
|
}
|
|
7904
7996
|
function buildRunCompletedProps(input) {
|
|
7905
7997
|
const totalMs = input.phases?.total_ms ?? Date.now() - input.startTime;
|
|
@@ -7980,7 +8072,7 @@ function failureStreakSampling(status, priorStreak, runId) {
|
|
|
7980
8072
|
if (priorStreak < FAILURE_STREAK_SAMPLE_AFTER) {
|
|
7981
8073
|
return { report: true, props: { failureStreak: priorStreak } };
|
|
7982
8074
|
}
|
|
7983
|
-
const bucket =
|
|
8075
|
+
const bucket = crypto5.createHash("sha256").update(runId).digest().readUInt32BE(0) % FAILURE_STREAK_SAMPLE_RATE;
|
|
7984
8076
|
return {
|
|
7985
8077
|
report: bucket === 0,
|
|
7986
8078
|
props: { failureStreak: priorStreak, sampleRate: FAILURE_STREAK_SAMPLE_RATE }
|
|
@@ -8053,7 +8145,7 @@ function getSharedProviderExecutionGate(providerName, maxConcurrency, maxPerMinu
|
|
|
8053
8145
|
}
|
|
8054
8146
|
|
|
8055
8147
|
// src/usage-quota.ts
|
|
8056
|
-
import
|
|
8148
|
+
import crypto6 from "crypto";
|
|
8057
8149
|
import { and as and2, eq as eq2, lte, sql } from "drizzle-orm";
|
|
8058
8150
|
function getCurrentUsageDay() {
|
|
8059
8151
|
return (/* @__PURE__ */ new Date()).toISOString().slice(0, 10);
|
|
@@ -8070,7 +8162,7 @@ function reserveDailyQueryQuota(db, input) {
|
|
|
8070
8162
|
)).run();
|
|
8071
8163
|
if (reserveExisting().changes === 1) return { reserved: true, used: 0 };
|
|
8072
8164
|
const inserted = tx.insert(usageCounters).values({
|
|
8073
|
-
id:
|
|
8165
|
+
id: crypto6.randomUUID(),
|
|
8074
8166
|
scope: input.scope,
|
|
8075
8167
|
period: input.period,
|
|
8076
8168
|
metric: "queries",
|
|
@@ -8665,7 +8757,7 @@ var JobRunner = class {
|
|
|
8665
8757
|
const answerLocation = runLocation && isSearchLocationIgnored(providerName, normalized.retrievalStatus) ? { location: null, requestedContext: runLocation, supportedContext: { status: "ignored" } } : { location: runLocation?.label ?? null };
|
|
8666
8758
|
let screenshotRelPath = null;
|
|
8667
8759
|
if (raw.screenshotPath && fs4.existsSync(raw.screenshotPath)) {
|
|
8668
|
-
const snapshotId =
|
|
8760
|
+
const snapshotId = crypto7.randomUUID();
|
|
8669
8761
|
const screenshotDir = path3.join(os3.homedir(), ".canonry", "screenshots", runId);
|
|
8670
8762
|
if (!fs4.existsSync(screenshotDir)) fs4.mkdirSync(screenshotDir, { recursive: true });
|
|
8671
8763
|
const destPath = path3.join(screenshotDir, `${snapshotId}.png`);
|
|
@@ -8709,7 +8801,7 @@ var JobRunner = class {
|
|
|
8709
8801
|
}).run();
|
|
8710
8802
|
} else {
|
|
8711
8803
|
this.db.insert(querySnapshots).values({
|
|
8712
|
-
id:
|
|
8804
|
+
id: crypto7.randomUUID(),
|
|
8713
8805
|
runId,
|
|
8714
8806
|
queryId: q.id,
|
|
8715
8807
|
queryText: q.query,
|
|
@@ -9249,7 +9341,7 @@ var JobRunner = class {
|
|
|
9249
9341
|
syncUnits.push(unit);
|
|
9250
9342
|
continue;
|
|
9251
9343
|
}
|
|
9252
|
-
const customId =
|
|
9344
|
+
const customId = crypto7.randomUUID().replace(/-/g, "");
|
|
9253
9345
|
const lines = linesByModel.get(model) ?? [];
|
|
9254
9346
|
lines.push({ unit, requestedModel, customId, request, bytes: Buffer.byteLength(JSON.stringify({ custom_id: customId, params: request.body })) });
|
|
9255
9347
|
linesByModel.set(model, lines);
|
|
@@ -9285,7 +9377,7 @@ var JobRunner = class {
|
|
|
9285
9377
|
if (!capability || !reservation) throw new Error(`Provider ${providerName} cannot submit a batch for run ${ctx.runId}`);
|
|
9286
9378
|
const deadlineMs = (config.batch?.deadlineHours ?? capability.defaultDeadlineHours) * HOUR_MS;
|
|
9287
9379
|
const created = /* @__PURE__ */ new Date();
|
|
9288
|
-
const rowId =
|
|
9380
|
+
const rowId = crypto7.randomUUID();
|
|
9289
9381
|
const ledger = lines.map((line) => ({
|
|
9290
9382
|
id: line.customId,
|
|
9291
9383
|
batchId: rowId,
|
|
@@ -9978,7 +10070,7 @@ var JobRunner = class {
|
|
|
9978
10070
|
competitorAliases
|
|
9979
10071
|
);
|
|
9980
10072
|
const answerContext = supportedContext && isSearchLocationIgnored(providerName, normalized.retrievalStatus) ? { status: "ignored" } : supportedContext;
|
|
9981
|
-
const snapshotId =
|
|
10073
|
+
const snapshotId = crypto7.randomUUID();
|
|
9982
10074
|
let screenshotRelPath = null;
|
|
9983
10075
|
if (raw.screenshotPath && fs4.existsSync(raw.screenshotPath)) {
|
|
9984
10076
|
const screenshotDir = path3.join(os3.homedir(), ".canonry", "screenshots", ctx.runId);
|
|
@@ -10080,7 +10172,7 @@ var JobRunner = class {
|
|
|
10080
10172
|
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
10081
10173
|
const period = now.slice(0, 10);
|
|
10082
10174
|
this.db.insert(usageCounters).values({
|
|
10083
|
-
id:
|
|
10175
|
+
id: crypto7.randomUUID(),
|
|
10084
10176
|
scope,
|
|
10085
10177
|
period,
|
|
10086
10178
|
metric,
|
|
@@ -10214,11 +10306,11 @@ function maybeShowActivationNotice(io = {}) {
|
|
|
10214
10306
|
}
|
|
10215
10307
|
|
|
10216
10308
|
// src/gsc-sync.ts
|
|
10217
|
-
import
|
|
10309
|
+
import crypto9 from "crypto";
|
|
10218
10310
|
import { eq as eq5, and as and5, sql as sql3 } from "drizzle-orm";
|
|
10219
10311
|
|
|
10220
10312
|
// src/gsc-coverage-snapshot.ts
|
|
10221
|
-
import
|
|
10313
|
+
import crypto8 from "crypto";
|
|
10222
10314
|
import { and as and4, desc as desc2, eq as eq4, gte } from "drizzle-orm";
|
|
10223
10315
|
var COVERAGE_IMPRESSION_WINDOW_DAYS = 30;
|
|
10224
10316
|
function pageKey(raw) {
|
|
@@ -10280,7 +10372,7 @@ function writeCoverageSnapshot(db, projectId, runId, opts = {}) {
|
|
|
10280
10372
|
const snapshotDate = now.toISOString().split("T")[0];
|
|
10281
10373
|
db.delete(gscCoverageSnapshots).where(and4(eq4(gscCoverageSnapshots.projectId, projectId), eq4(gscCoverageSnapshots.date, snapshotDate))).run();
|
|
10282
10374
|
db.insert(gscCoverageSnapshots).values({
|
|
10283
|
-
id:
|
|
10375
|
+
id: crypto8.randomUUID(),
|
|
10284
10376
|
projectId,
|
|
10285
10377
|
syncRunId: runId,
|
|
10286
10378
|
date: snapshotDate,
|
|
@@ -10359,7 +10451,7 @@ async function executeGscSync(db, runId, projectId, opts) {
|
|
|
10359
10451
|
for (const row of batch) {
|
|
10360
10452
|
const [query, page, country, device, date] = row.keys;
|
|
10361
10453
|
db.insert(gscSearchData).values({
|
|
10362
|
-
id:
|
|
10454
|
+
id: crypto9.randomUUID(),
|
|
10363
10455
|
projectId,
|
|
10364
10456
|
syncRunId: runId,
|
|
10365
10457
|
date: date ?? "",
|
|
@@ -10391,7 +10483,7 @@ async function executeGscSync(db, runId, projectId, opts) {
|
|
|
10391
10483
|
for (const row of totalRows) {
|
|
10392
10484
|
const [date] = row.keys;
|
|
10393
10485
|
db.insert(gscDailyTotals).values({
|
|
10394
|
-
id:
|
|
10486
|
+
id: crypto9.randomUUID(),
|
|
10395
10487
|
projectId,
|
|
10396
10488
|
date: date ?? "",
|
|
10397
10489
|
clicks: row.clicks,
|
|
@@ -10440,7 +10532,7 @@ async function executeGscSync(db, runId, projectId, opts) {
|
|
|
10440
10532
|
const [date, query] = row.keys;
|
|
10441
10533
|
if (!date || !query) continue;
|
|
10442
10534
|
db.insert(gscQueryDailyTotals).values({
|
|
10443
|
-
id:
|
|
10535
|
+
id: crypto9.randomUUID(),
|
|
10444
10536
|
projectId,
|
|
10445
10537
|
date,
|
|
10446
10538
|
query,
|
|
@@ -10465,11 +10557,11 @@ async function executeGscSync(db, runId, projectId, opts) {
|
|
|
10465
10557
|
}
|
|
10466
10558
|
|
|
10467
10559
|
// src/gbp-sync.ts
|
|
10468
|
-
import
|
|
10560
|
+
import crypto11 from "crypto";
|
|
10469
10561
|
import { eq as eq7, and as and7, desc as desc4, inArray as inArray3, lt as lt2 } from "drizzle-orm";
|
|
10470
10562
|
|
|
10471
10563
|
// src/gbp-reviews.ts
|
|
10472
|
-
import
|
|
10564
|
+
import crypto10 from "crypto";
|
|
10473
10565
|
import { and as and6, desc as desc3, eq as eq6, inArray as inArray2, sql as sql4 } from "drizzle-orm";
|
|
10474
10566
|
var log4 = createLogger("GbpReviews");
|
|
10475
10567
|
var MS_PER_DAY = 864e5;
|
|
@@ -10588,7 +10680,7 @@ function persistReviewObservation(tx, projectId, runId, obs, ctx) {
|
|
|
10588
10680
|
let queuedRatingDrop = false;
|
|
10589
10681
|
if (!latestRating) {
|
|
10590
10682
|
tx.insert(gbpReviewRatings).values({
|
|
10591
|
-
id:
|
|
10683
|
+
id: crypto10.randomUUID(),
|
|
10592
10684
|
projectId,
|
|
10593
10685
|
locationName: obs.locationName,
|
|
10594
10686
|
origin: obs.origin,
|
|
@@ -10608,7 +10700,7 @@ function persistReviewObservation(tx, projectId, runId, obs, ctx) {
|
|
|
10608
10700
|
const alertState = ratingAlertState(obs.origin, latestRating.rating, obs.rating);
|
|
10609
10701
|
queuedRatingDrop = alertState === "pending";
|
|
10610
10702
|
tx.insert(gbpReviewRatings).values({
|
|
10611
|
-
id:
|
|
10703
|
+
id: crypto10.randomUUID(),
|
|
10612
10704
|
projectId,
|
|
10613
10705
|
locationName: obs.locationName,
|
|
10614
10706
|
origin: obs.origin,
|
|
@@ -10658,7 +10750,7 @@ function persistReviewObservation(tx, projectId, runId, obs, ctx) {
|
|
|
10658
10750
|
const alertState = reviewAlertState(review, { baseline, now, negativeMaxStars });
|
|
10659
10751
|
if (alertState === "pending") queuedReviews++;
|
|
10660
10752
|
tx.insert(gbpReviews).values({
|
|
10661
|
-
id:
|
|
10753
|
+
id: crypto10.randomUUID(),
|
|
10662
10754
|
projectId,
|
|
10663
10755
|
origin: obs.origin,
|
|
10664
10756
|
reviewName: review.reviewName,
|
|
@@ -10819,7 +10911,7 @@ async function executeGbpSync(db, runId, projectId, opts) {
|
|
|
10819
10911
|
tx.delete(gbpDailyMetrics).where(and7(eq7(gbpDailyMetrics.projectId, projectId), eq7(gbpDailyMetrics.locationName, loc.locationName))).run();
|
|
10820
10912
|
for (const row of metricRows) {
|
|
10821
10913
|
tx.insert(gbpDailyMetrics).values({
|
|
10822
|
-
id:
|
|
10914
|
+
id: crypto11.randomUUID(),
|
|
10823
10915
|
projectId,
|
|
10824
10916
|
locationName: loc.locationName,
|
|
10825
10917
|
date: row.date,
|
|
@@ -10831,7 +10923,7 @@ async function executeGbpSync(db, runId, projectId, opts) {
|
|
|
10831
10923
|
tx.delete(gbpKeywordImpressions).where(and7(eq7(gbpKeywordImpressions.projectId, projectId), eq7(gbpKeywordImpressions.locationName, loc.locationName))).run();
|
|
10832
10924
|
for (const row of keywordRows) {
|
|
10833
10925
|
tx.insert(gbpKeywordImpressions).values({
|
|
10834
|
-
id:
|
|
10926
|
+
id: crypto11.randomUUID(),
|
|
10835
10927
|
projectId,
|
|
10836
10928
|
locationName: loc.locationName,
|
|
10837
10929
|
periodStart: monthKey(keywordsStart),
|
|
@@ -10852,7 +10944,7 @@ async function executeGbpSync(db, runId, projectId, opts) {
|
|
|
10852
10944
|
for (const { month, rows } of monthlyKeywordResults) {
|
|
10853
10945
|
for (const row of rows) {
|
|
10854
10946
|
tx.insert(gbpKeywordMonthly).values({
|
|
10855
|
-
id:
|
|
10947
|
+
id: crypto11.randomUUID(),
|
|
10856
10948
|
projectId,
|
|
10857
10949
|
locationName: loc.locationName,
|
|
10858
10950
|
month,
|
|
@@ -10873,7 +10965,7 @@ async function executeGbpSync(db, runId, projectId, opts) {
|
|
|
10873
10965
|
tx.delete(gbpPlaceActions).where(and7(eq7(gbpPlaceActions.projectId, projectId), eq7(gbpPlaceActions.locationName, loc.locationName))).run();
|
|
10874
10966
|
for (const row of placeActionRows) {
|
|
10875
10967
|
tx.insert(gbpPlaceActions).values({
|
|
10876
|
-
id:
|
|
10968
|
+
id: crypto11.randomUUID(),
|
|
10877
10969
|
projectId,
|
|
10878
10970
|
locationName: loc.locationName,
|
|
10879
10971
|
placeActionLinkName: row.placeActionLinkName,
|
|
@@ -10886,7 +10978,7 @@ async function executeGbpSync(db, runId, projectId, opts) {
|
|
|
10886
10978
|
}
|
|
10887
10979
|
if (lodging !== null && lodgingChanged) {
|
|
10888
10980
|
tx.insert(gbpLodgingSnapshots).values({
|
|
10889
|
-
id:
|
|
10981
|
+
id: crypto11.randomUUID(),
|
|
10890
10982
|
projectId,
|
|
10891
10983
|
locationName: loc.locationName,
|
|
10892
10984
|
contentHash: lodgingHash,
|
|
@@ -10900,7 +10992,7 @@ async function executeGbpSync(db, runId, projectId, opts) {
|
|
|
10900
10992
|
}
|
|
10901
10993
|
if (attributesChanged) {
|
|
10902
10994
|
tx.insert(gbpAttributesSnapshots).values({
|
|
10903
|
-
id:
|
|
10995
|
+
id: crypto11.randomUUID(),
|
|
10904
10996
|
projectId,
|
|
10905
10997
|
locationName: loc.locationName,
|
|
10906
10998
|
contentHash: attributesHash,
|
|
@@ -10914,7 +11006,7 @@ async function executeGbpSync(db, runId, projectId, opts) {
|
|
|
10914
11006
|
}
|
|
10915
11007
|
if (placeToWrite) {
|
|
10916
11008
|
tx.insert(gbpPlaceDetails).values({
|
|
10917
|
-
id:
|
|
11009
|
+
id: crypto11.randomUUID(),
|
|
10918
11010
|
projectId,
|
|
10919
11011
|
locationName: loc.locationName,
|
|
10920
11012
|
placeId: placeToWrite.placeId,
|
|
@@ -11019,7 +11111,7 @@ async function refreshSelectedLocationProfiles(db, projectId, accessToken, locat
|
|
|
11019
11111
|
}
|
|
11020
11112
|
|
|
11021
11113
|
// src/ads-sync.ts
|
|
11022
|
-
import
|
|
11114
|
+
import crypto12 from "crypto";
|
|
11023
11115
|
import { and as and8, eq as eq8, inArray as inArray4, notInArray } from "drizzle-orm";
|
|
11024
11116
|
|
|
11025
11117
|
// ../integration-openai-ads/src/constants.ts
|
|
@@ -11794,7 +11886,7 @@ async function executeAdsSync(db, runId, projectId, opts) {
|
|
|
11794
11886
|
}
|
|
11795
11887
|
for (const upsert of insightUpserts) {
|
|
11796
11888
|
tx.insert(adsInsightsDaily).values({
|
|
11797
|
-
id:
|
|
11889
|
+
id: crypto12.randomUUID(),
|
|
11798
11890
|
projectId,
|
|
11799
11891
|
level: upsert.level,
|
|
11800
11892
|
entityId: upsert.entityId,
|
|
@@ -11862,7 +11954,7 @@ async function executeAdsSync(db, runId, projectId, opts) {
|
|
|
11862
11954
|
}
|
|
11863
11955
|
|
|
11864
11956
|
// src/gsc-inspect-sitemap.ts
|
|
11865
|
-
import
|
|
11957
|
+
import crypto14 from "crypto";
|
|
11866
11958
|
import { eq as eq9 } from "drizzle-orm";
|
|
11867
11959
|
|
|
11868
11960
|
// src/sitemap-parser.ts
|
|
@@ -11962,7 +12054,7 @@ async function parseSitemapRecursive(url, urls, visited, depth, isChild) {
|
|
|
11962
12054
|
}
|
|
11963
12055
|
|
|
11964
12056
|
// src/inspect-rate-gate.ts
|
|
11965
|
-
import
|
|
12057
|
+
import crypto13 from "crypto";
|
|
11966
12058
|
var gates = /* @__PURE__ */ new Map();
|
|
11967
12059
|
function sharedRateGate(key) {
|
|
11968
12060
|
let entry = gates.get(key);
|
|
@@ -11981,7 +12073,7 @@ function sharedRateGate(key) {
|
|
|
11981
12073
|
};
|
|
11982
12074
|
}
|
|
11983
12075
|
function credentialGateKey(prefix, secret) {
|
|
11984
|
-
const digest =
|
|
12076
|
+
const digest = crypto13.createHash("sha256").update(secret).digest("hex").slice(0, 12);
|
|
11985
12077
|
return `${prefix}:${digest}`;
|
|
11986
12078
|
}
|
|
11987
12079
|
|
|
@@ -12136,7 +12228,7 @@ async function executeInspectSitemap(db, runId, projectId, opts) {
|
|
|
12136
12228
|
const rich = ir.richResultsResult;
|
|
12137
12229
|
const inspectedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
12138
12230
|
db.insert(gscUrlInspections).values({
|
|
12139
|
-
id:
|
|
12231
|
+
id: crypto14.randomUUID(),
|
|
12140
12232
|
projectId,
|
|
12141
12233
|
syncRunId: runId,
|
|
12142
12234
|
url: pageUrl,
|
|
@@ -12194,7 +12286,7 @@ async function executeInspectSitemap(db, runId, projectId, opts) {
|
|
|
12194
12286
|
}
|
|
12195
12287
|
|
|
12196
12288
|
// src/bing-inspect-sitemap.ts
|
|
12197
|
-
import
|
|
12289
|
+
import crypto15 from "crypto";
|
|
12198
12290
|
import { eq as eq10, desc as desc5 } from "drizzle-orm";
|
|
12199
12291
|
var log9 = createLogger("BingInspectSitemap");
|
|
12200
12292
|
var BING_INSPECT_SPACING_MS = 2e3;
|
|
@@ -12299,7 +12391,7 @@ async function executeBingInspectSitemap(db, runId, projectId, opts) {
|
|
|
12299
12391
|
derivedInIndex = false;
|
|
12300
12392
|
}
|
|
12301
12393
|
db.insert(bingUrlInspections).values({
|
|
12302
|
-
id:
|
|
12394
|
+
id: crypto15.randomUUID(),
|
|
12303
12395
|
projectId,
|
|
12304
12396
|
url: pageUrl,
|
|
12305
12397
|
httpCode,
|
|
@@ -12383,7 +12475,7 @@ async function executeBingInspectSitemap(db, runId, projectId, opts) {
|
|
|
12383
12475
|
const snapshotDate = (/* @__PURE__ */ new Date()).toISOString().split("T")[0];
|
|
12384
12476
|
const snapNow = (/* @__PURE__ */ new Date()).toISOString();
|
|
12385
12477
|
db.insert(bingCoverageSnapshots).values({
|
|
12386
|
-
id:
|
|
12478
|
+
id: crypto15.randomUUID(),
|
|
12387
12479
|
projectId,
|
|
12388
12480
|
syncRunId: runId,
|
|
12389
12481
|
date: snapshotDate,
|
|
@@ -12424,7 +12516,7 @@ async function executeBingInspectSitemap(db, runId, projectId, opts) {
|
|
|
12424
12516
|
}
|
|
12425
12517
|
|
|
12426
12518
|
// src/coverage-refresh.ts
|
|
12427
|
-
import
|
|
12519
|
+
import crypto16 from "crypto";
|
|
12428
12520
|
import { and as and9, desc as desc6, eq as eq11, inArray as inArray5 } from "drizzle-orm";
|
|
12429
12521
|
var log10 = createLogger("CoverageRefresh");
|
|
12430
12522
|
var COVERAGE_REFRESH_MIN_INTERVAL_MS = 60 * 60 * 1e3;
|
|
@@ -12474,7 +12566,7 @@ async function maybeRefreshGscCoverage(db, config, projectId, deps = defaultDeps
|
|
|
12474
12566
|
return null;
|
|
12475
12567
|
}
|
|
12476
12568
|
}
|
|
12477
|
-
const runId =
|
|
12569
|
+
const runId = crypto16.randomUUID();
|
|
12478
12570
|
db.insert(runs).values({
|
|
12479
12571
|
id: runId,
|
|
12480
12572
|
projectId,
|
|
@@ -12497,7 +12589,7 @@ async function maybeRefreshGscCoverage(db, config, projectId, deps = defaultDeps
|
|
|
12497
12589
|
}
|
|
12498
12590
|
|
|
12499
12591
|
// src/commoncrawl-sync.ts
|
|
12500
|
-
import
|
|
12592
|
+
import crypto17 from "crypto";
|
|
12501
12593
|
import path4 from "path";
|
|
12502
12594
|
import { and as and10, eq as eq12, sql as sql5 } from "drizzle-orm";
|
|
12503
12595
|
var log11 = createLogger("CommonCrawlSync");
|
|
@@ -12572,7 +12664,7 @@ async function executeReleaseSync(db, syncId, opts) {
|
|
|
12572
12664
|
if (!projectIds) continue;
|
|
12573
12665
|
for (const projectId of projectIds) {
|
|
12574
12666
|
expanded.push({
|
|
12575
|
-
id:
|
|
12667
|
+
id: crypto17.randomUUID(),
|
|
12576
12668
|
projectId,
|
|
12577
12669
|
releaseSyncId: syncId,
|
|
12578
12670
|
release,
|
|
@@ -12592,7 +12684,7 @@ async function executeReleaseSync(db, syncId, opts) {
|
|
|
12592
12684
|
const projectRows = rowsByProject.get(p.id) ?? [];
|
|
12593
12685
|
const summary = computeSummary(projectRows);
|
|
12594
12686
|
tx.insert(backlinkSummaries).values({
|
|
12595
|
-
id:
|
|
12687
|
+
id: crypto17.randomUUID(),
|
|
12596
12688
|
projectId: p.id,
|
|
12597
12689
|
releaseSyncId: syncId,
|
|
12598
12690
|
source: BacklinkSources.commoncrawl,
|
|
@@ -12689,7 +12781,7 @@ function computeSummary(rows) {
|
|
|
12689
12781
|
}
|
|
12690
12782
|
|
|
12691
12783
|
// src/backlink-extract.ts
|
|
12692
|
-
import
|
|
12784
|
+
import crypto18 from "crypto";
|
|
12693
12785
|
import fs5 from "fs";
|
|
12694
12786
|
import { and as and11, desc as desc7, eq as eq13 } from "drizzle-orm";
|
|
12695
12787
|
var log12 = createLogger("BacklinkExtract");
|
|
@@ -12745,7 +12837,7 @@ async function executeBacklinkExtract(db, runId, projectId, opts = {}) {
|
|
|
12745
12837
|
).run();
|
|
12746
12838
|
if (rows.length > 0) {
|
|
12747
12839
|
const values = rows.map((r) => ({
|
|
12748
|
-
id:
|
|
12840
|
+
id: crypto18.randomUUID(),
|
|
12749
12841
|
projectId,
|
|
12750
12842
|
releaseSyncId: syncId,
|
|
12751
12843
|
source: BacklinkSources.commoncrawl,
|
|
@@ -12759,7 +12851,7 @@ async function executeBacklinkExtract(db, runId, projectId, opts = {}) {
|
|
|
12759
12851
|
}
|
|
12760
12852
|
const summary = computeSummary2(rows);
|
|
12761
12853
|
tx.insert(backlinkSummaries).values({
|
|
12762
|
-
id:
|
|
12854
|
+
id: crypto18.randomUUID(),
|
|
12763
12855
|
projectId,
|
|
12764
12856
|
releaseSyncId: syncId,
|
|
12765
12857
|
source: BacklinkSources.commoncrawl,
|
|
@@ -12802,7 +12894,7 @@ function computeSummary2(rows) {
|
|
|
12802
12894
|
}
|
|
12803
12895
|
|
|
12804
12896
|
// src/discovery-run.ts
|
|
12805
|
-
import
|
|
12897
|
+
import crypto19 from "crypto";
|
|
12806
12898
|
import { and as and12, eq as eq14 } from "drizzle-orm";
|
|
12807
12899
|
var log13 = createLogger("DiscoveryRun");
|
|
12808
12900
|
var DEFAULT_SEED_COUNT = 30;
|
|
@@ -13157,7 +13249,7 @@ function writeDiscoveryInsight(db, input) {
|
|
|
13157
13249
|
eq14(insights.dismissed, false)
|
|
13158
13250
|
)).run();
|
|
13159
13251
|
tx.insert(insights).values({
|
|
13160
|
-
id:
|
|
13252
|
+
id: crypto19.randomUUID(),
|
|
13161
13253
|
projectId: input.projectId,
|
|
13162
13254
|
runId: input.runId,
|
|
13163
13255
|
type: "discovery.basket-divergence",
|
|
@@ -13193,7 +13285,7 @@ function buildDiscoveryInsightTitle(input) {
|
|
|
13193
13285
|
}
|
|
13194
13286
|
|
|
13195
13287
|
// src/execute-site-audit.ts
|
|
13196
|
-
import
|
|
13288
|
+
import crypto20 from "crypto";
|
|
13197
13289
|
import { and as and14, eq as eq16, ne as ne2, sql as sql6 } from "drizzle-orm";
|
|
13198
13290
|
import { runSiteCrawl } from "@canonry/aeo-audit";
|
|
13199
13291
|
|
|
@@ -13644,7 +13736,7 @@ async function executeSiteAudit(db, runId, projectId, opts = {}) {
|
|
|
13644
13736
|
const trigger = db.select({ trigger: runs.trigger }).from(runs).where(eq16(runs.id, runId)).get()?.trigger ?? null;
|
|
13645
13737
|
let canonicalDomain = null;
|
|
13646
13738
|
const attemptNumber = (db.select({ value: sql6`coalesce(max(${siteCrawlAttempts.attemptNumber}), 0)` }).from(siteCrawlAttempts).where(eq16(siteCrawlAttempts.runId, runId)).get()?.value ?? 0) + 1;
|
|
13647
|
-
const attemptId =
|
|
13739
|
+
const attemptId = crypto20.randomUUID();
|
|
13648
13740
|
db.insert(siteCrawlAttempts).values({
|
|
13649
13741
|
id: attemptId,
|
|
13650
13742
|
projectId,
|
|
@@ -13722,7 +13814,7 @@ async function executeSiteAudit(db, runId, projectId, opts = {}) {
|
|
|
13722
13814
|
nodeKey: page.key
|
|
13723
13815
|
});
|
|
13724
13816
|
tx.insert(siteCrawlPages).values({
|
|
13725
|
-
id:
|
|
13817
|
+
id: crypto20.randomUUID(),
|
|
13726
13818
|
projectId,
|
|
13727
13819
|
runId,
|
|
13728
13820
|
attemptId,
|
|
@@ -13815,7 +13907,7 @@ async function executeSiteAudit(db, runId, projectId, opts = {}) {
|
|
|
13815
13907
|
if (isSelfLink(edge.from, edge.to)) return;
|
|
13816
13908
|
observedEdges.set(edge.key, edge);
|
|
13817
13909
|
tx.insert(siteCrawlEdges).values({
|
|
13818
|
-
id:
|
|
13910
|
+
id: crypto20.randomUUID(),
|
|
13819
13911
|
projectId,
|
|
13820
13912
|
runId,
|
|
13821
13913
|
attemptId,
|
|
@@ -13885,7 +13977,7 @@ async function executeSiteAudit(db, runId, projectId, opts = {}) {
|
|
|
13885
13977
|
return;
|
|
13886
13978
|
}
|
|
13887
13979
|
tx.insert(siteCrawlEventReceipts).values({
|
|
13888
|
-
id:
|
|
13980
|
+
id: crypto20.randomUUID(),
|
|
13889
13981
|
projectId,
|
|
13890
13982
|
runId,
|
|
13891
13983
|
attemptId,
|
|
@@ -14021,7 +14113,7 @@ async function executeSiteAudit(db, runId, projectId, opts = {}) {
|
|
|
14021
14113
|
if (claim2.changes === 0) return false;
|
|
14022
14114
|
if (hasAuditedPages) {
|
|
14023
14115
|
tx.insert(siteAuditSnapshots).values({
|
|
14024
|
-
id:
|
|
14116
|
+
id: crypto20.randomUUID(),
|
|
14025
14117
|
projectId,
|
|
14026
14118
|
runId,
|
|
14027
14119
|
sitemapUrl: opts.sitemapUrl ?? new URL("/sitemap.xml", crawlRootUrl).href,
|
|
@@ -14039,7 +14131,7 @@ async function executeSiteAudit(db, runId, projectId, opts = {}) {
|
|
|
14039
14131
|
for (const page of observedPages.values()) {
|
|
14040
14132
|
if (!isLegacyScorecardPage(page)) continue;
|
|
14041
14133
|
tx.insert(siteAuditPages).values({
|
|
14042
|
-
id:
|
|
14134
|
+
id: crypto20.randomUUID(),
|
|
14043
14135
|
projectId,
|
|
14044
14136
|
runId,
|
|
14045
14137
|
url: page.finalUrl ?? page.requestedUrl,
|
|
@@ -14052,7 +14144,7 @@ async function executeSiteAudit(db, runId, projectId, opts = {}) {
|
|
|
14052
14144
|
}
|
|
14053
14145
|
}
|
|
14054
14146
|
tx.insert(siteCrawlSnapshots).values({
|
|
14055
|
-
id:
|
|
14147
|
+
id: crypto20.randomUUID(),
|
|
14056
14148
|
projectId,
|
|
14057
14149
|
runId,
|
|
14058
14150
|
attemptId,
|
|
@@ -14098,7 +14190,7 @@ async function executeSiteAudit(db, runId, projectId, opts = {}) {
|
|
|
14098
14190
|
if (opts.checkDeadLinks) {
|
|
14099
14191
|
for (const finding of deadLinkFindings) {
|
|
14100
14192
|
tx.insert(siteCrawlFindings).values({
|
|
14101
|
-
id:
|
|
14193
|
+
id: crypto20.randomUUID(),
|
|
14102
14194
|
projectId,
|
|
14103
14195
|
runId,
|
|
14104
14196
|
attemptId,
|
|
@@ -14673,7 +14765,7 @@ function readStoredGroundingSources(rawResponse) {
|
|
|
14673
14765
|
return result2;
|
|
14674
14766
|
}
|
|
14675
14767
|
async function backfillInsightsCommand(project, opts) {
|
|
14676
|
-
const { IntelligenceService: IntelligenceService2 } = await import("./intelligence-service-
|
|
14768
|
+
const { IntelligenceService: IntelligenceService2 } = await import("./intelligence-service-5J36RBEM.js");
|
|
14677
14769
|
const config = loadConfig();
|
|
14678
14770
|
const db = createClient(config.database);
|
|
14679
14771
|
migrate(db);
|
|
@@ -15263,7 +15355,7 @@ var ProviderRegistry = class {
|
|
|
15263
15355
|
import { createHash as createHash4 } from "crypto";
|
|
15264
15356
|
var TTL_MS = 60 * 60 * 1e3;
|
|
15265
15357
|
var RETRY_MS = 60 * 1e3;
|
|
15266
|
-
var
|
|
15358
|
+
var TIMEOUT_MS3 = 3e3;
|
|
15267
15359
|
function createProviderModelCatalog(registry) {
|
|
15268
15360
|
const cache = /* @__PURE__ */ new Map();
|
|
15269
15361
|
const read = async (name) => {
|
|
@@ -15289,7 +15381,7 @@ function createProviderModelCatalog(registry) {
|
|
|
15289
15381
|
timer = setTimeout(() => {
|
|
15290
15382
|
controller.abort();
|
|
15291
15383
|
reject(new Error("Model discovery timed out"));
|
|
15292
|
-
},
|
|
15384
|
+
}, TIMEOUT_MS3);
|
|
15293
15385
|
});
|
|
15294
15386
|
current.pending = Promise.race([
|
|
15295
15387
|
Promise.resolve().then(() => provider.adapter.listModels(provider.config, controller.signal)),
|
|
@@ -15320,14 +15412,14 @@ function createProviderModelCatalog(registry) {
|
|
|
15320
15412
|
}
|
|
15321
15413
|
|
|
15322
15414
|
// src/scheduler.ts
|
|
15323
|
-
import
|
|
15415
|
+
import crypto21 from "crypto";
|
|
15324
15416
|
import cron from "node-cron";
|
|
15325
15417
|
import { and as and16, eq as eq18, inArray as inArray8, notExists, sql as sql8 } from "drizzle-orm";
|
|
15326
15418
|
var log15 = createLogger("Scheduler");
|
|
15327
15419
|
var DEFAULT_HEALTH_CRON = "0 */6 * * *";
|
|
15328
15420
|
function ensureDefaultHealthSchedule(db, projectId, now = (/* @__PURE__ */ new Date()).toISOString()) {
|
|
15329
15421
|
const result2 = db.insert(schedules).values({
|
|
15330
|
-
id:
|
|
15422
|
+
id: crypto21.randomUUID(),
|
|
15331
15423
|
projectId,
|
|
15332
15424
|
kind: SchedulableRunKinds.doctor,
|
|
15333
15425
|
cronExpr: DEFAULT_HEALTH_CRON,
|
|
@@ -15645,7 +15737,7 @@ var Scheduler = class {
|
|
|
15645
15737
|
log15.warn("gbp-sync.no-callback", { scheduleId, projectId, msg: "host did not register onGbpSyncRequested" });
|
|
15646
15738
|
return;
|
|
15647
15739
|
}
|
|
15648
|
-
const runId2 =
|
|
15740
|
+
const runId2 = crypto21.randomUUID();
|
|
15649
15741
|
this.db.insert(runs).values({
|
|
15650
15742
|
id: runId2,
|
|
15651
15743
|
projectId,
|
|
@@ -15677,7 +15769,7 @@ var Scheduler = class {
|
|
|
15677
15769
|
this.updateScheduleTiming(currentSchedule.id, { nextRunAt });
|
|
15678
15770
|
return;
|
|
15679
15771
|
}
|
|
15680
|
-
const runId2 =
|
|
15772
|
+
const runId2 = crypto21.randomUUID();
|
|
15681
15773
|
this.db.insert(runs).values({
|
|
15682
15774
|
id: runId2,
|
|
15683
15775
|
projectId,
|
|
@@ -15748,7 +15840,7 @@ var Scheduler = class {
|
|
|
15748
15840
|
this.updateScheduleTiming(currentSchedule.id, { nextRunAt });
|
|
15749
15841
|
return;
|
|
15750
15842
|
}
|
|
15751
|
-
const runId2 =
|
|
15843
|
+
const runId2 = crypto21.randomUUID();
|
|
15752
15844
|
const effectiveRequest = normalizeSiteAuditRunRequest({ maxPages: SITE_AUDIT_MAX_PAGE_LIMIT });
|
|
15753
15845
|
this.db.transaction((tx) => {
|
|
15754
15846
|
tx.insert(runs).values({
|
|
@@ -16091,7 +16183,7 @@ async function refreshAllIntegrations(client, projectName, now = /* @__PURE__ */
|
|
|
16091
16183
|
|
|
16092
16184
|
// src/notifier.ts
|
|
16093
16185
|
import { eq as eq20, desc as desc9, and as and18, inArray as inArray10, or } from "drizzle-orm";
|
|
16094
|
-
import
|
|
16186
|
+
import crypto22 from "crypto";
|
|
16095
16187
|
var log19 = createLogger("Notifier");
|
|
16096
16188
|
var MATERIAL_MAGNITUDE_DELTA = 20;
|
|
16097
16189
|
var SEVERITY_RANK = { low: 0, medium: 1, high: 2, critical: 3 };
|
|
@@ -16718,7 +16810,7 @@ var Notifier = class {
|
|
|
16718
16810
|
}
|
|
16719
16811
|
logDelivery(projectId, notificationId, event, status, error) {
|
|
16720
16812
|
this.db.insert(auditLog).values({
|
|
16721
|
-
id:
|
|
16813
|
+
id: crypto22.randomUUID(),
|
|
16722
16814
|
projectId,
|
|
16723
16815
|
actor: "scheduler",
|
|
16724
16816
|
action: `notification.${status}`,
|
|
@@ -16894,7 +16986,7 @@ function analysisResultFromInsights(insights2) {
|
|
|
16894
16986
|
}
|
|
16895
16987
|
|
|
16896
16988
|
// src/agent/session-registry.ts
|
|
16897
|
-
import
|
|
16989
|
+
import crypto26 from "crypto";
|
|
16898
16990
|
import { eq as eq24 } from "drizzle-orm";
|
|
16899
16991
|
|
|
16900
16992
|
// src/agent/session.ts
|
|
@@ -18147,7 +18239,7 @@ function buildAeroStateTools(ctx, opts = {}) {
|
|
|
18147
18239
|
}
|
|
18148
18240
|
|
|
18149
18241
|
// src/agent/llm-usage.ts
|
|
18150
|
-
import
|
|
18242
|
+
import crypto23 from "crypto";
|
|
18151
18243
|
var AeroLlmUsageFeatures = {
|
|
18152
18244
|
turn: "aero.turn"
|
|
18153
18245
|
};
|
|
@@ -18166,7 +18258,7 @@ function recordLlmUsageEvent(args) {
|
|
|
18166
18258
|
const usage = args.message.usage;
|
|
18167
18259
|
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
18168
18260
|
args.db.insert(llmUsageEvents).values({
|
|
18169
|
-
id:
|
|
18261
|
+
id: crypto23.randomUUID(),
|
|
18170
18262
|
projectId: args.projectId,
|
|
18171
18263
|
runId: args.runId,
|
|
18172
18264
|
agentSessionId: args.agentSessionId,
|
|
@@ -18536,7 +18628,7 @@ This context applies to this turn. Explicit user scope takes precedence; do not
|
|
|
18536
18628
|
}
|
|
18537
18629
|
|
|
18538
18630
|
// src/agent/tool-usage.ts
|
|
18539
|
-
import
|
|
18631
|
+
import crypto24 from "crypto";
|
|
18540
18632
|
var AeroToolEventStatuses = {
|
|
18541
18633
|
success: "success",
|
|
18542
18634
|
error: "error"
|
|
@@ -18599,7 +18691,7 @@ function createAeroToolUsageHooks(args) {
|
|
|
18599
18691
|
function recordAgentToolEvent(args) {
|
|
18600
18692
|
try {
|
|
18601
18693
|
args.db.insert(agentToolEvents).values({
|
|
18602
|
-
id:
|
|
18694
|
+
id: crypto24.randomUUID(),
|
|
18603
18695
|
projectId: args.projectId,
|
|
18604
18696
|
agentSessionId: args.agentSessionId,
|
|
18605
18697
|
toolCallId: args.toolCallId,
|
|
@@ -18854,7 +18946,7 @@ async function loadExternalMcpTools(servers, opts = {}) {
|
|
|
18854
18946
|
}
|
|
18855
18947
|
|
|
18856
18948
|
// src/agent/memory-store.ts
|
|
18857
|
-
import
|
|
18949
|
+
import crypto25 from "crypto";
|
|
18858
18950
|
import { and as and19, desc as desc10, eq as eq22, like, sql as sql10, or as or2 } from "drizzle-orm";
|
|
18859
18951
|
var COMPACTION_KEY_PREFIX = "compaction:";
|
|
18860
18952
|
var COMPACTION_NOTES_PER_SESSION = 3;
|
|
@@ -18883,7 +18975,7 @@ function upsertMemoryEntry(db, args) {
|
|
|
18883
18975
|
throw new Error(`memory key prefix "${COMPACTION_KEY_PREFIX}" is reserved for compaction notes`);
|
|
18884
18976
|
}
|
|
18885
18977
|
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
18886
|
-
const id =
|
|
18978
|
+
const id = crypto25.randomUUID();
|
|
18887
18979
|
db.insert(agentMemory).values({
|
|
18888
18980
|
id,
|
|
18889
18981
|
projectId: args.projectId,
|
|
@@ -18925,7 +19017,7 @@ function writeCompactionNote(db, args) {
|
|
|
18925
19017
|
}
|
|
18926
19018
|
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
18927
19019
|
const key = `${COMPACTION_KEY_PREFIX}${args.sessionId}:${now}`;
|
|
18928
|
-
const id =
|
|
19020
|
+
const id = crypto25.randomUUID();
|
|
18929
19021
|
let inserted;
|
|
18930
19022
|
db.transaction((tx) => {
|
|
18931
19023
|
tx.insert(agentMemory).values({
|
|
@@ -19297,7 +19389,7 @@ var SessionRegistry = class {
|
|
|
19297
19389
|
return agent2;
|
|
19298
19390
|
}
|
|
19299
19391
|
const { provider, modelId } = resolveSessionProviderAndModel(this.opts.config, preferences);
|
|
19300
|
-
const sessionId =
|
|
19392
|
+
const sessionId = crypto26.randomUUID();
|
|
19301
19393
|
const agent = createAeroSession({
|
|
19302
19394
|
projectName,
|
|
19303
19395
|
client: this.opts.client,
|
|
@@ -19749,7 +19841,7 @@ ${lines.join("\n")}
|
|
|
19749
19841
|
insertRow(params) {
|
|
19750
19842
|
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
19751
19843
|
this.opts.db.insert(agentSessions).values({
|
|
19752
|
-
id: params.id ??
|
|
19844
|
+
id: params.id ?? crypto26.randomUUID(),
|
|
19753
19845
|
projectId: params.projectId,
|
|
19754
19846
|
systemPrompt: params.systemPrompt,
|
|
19755
19847
|
modelProvider: params.provider ?? params.modelProvider ?? AgentProviderIds.claude,
|
|
@@ -19776,7 +19868,7 @@ ${lines.join("\n")}
|
|
|
19776
19868
|
};
|
|
19777
19869
|
|
|
19778
19870
|
// src/agent/viewer-sessions.ts
|
|
19779
|
-
import
|
|
19871
|
+
import crypto27 from "crypto";
|
|
19780
19872
|
import { and as and21, eq as eq25, isNotNull as isNotNull3, like as like2 } from "drizzle-orm";
|
|
19781
19873
|
var AERO_VIEWER_EXCLUDED_MCP_TOOLS = /* @__PURE__ */ new Set([
|
|
19782
19874
|
CanonryMcpToolNames.canonry_ads_account,
|
|
@@ -19830,8 +19922,8 @@ function trimViewerTranscript(messages, max = MAX_VIEWER_MESSAGES) {
|
|
|
19830
19922
|
}
|
|
19831
19923
|
var VIEWER_IDLE_MS = 12 * 60 * 60 * 1e3;
|
|
19832
19924
|
function mintViewerAeroKey(db, userId, now = /* @__PURE__ */ new Date()) {
|
|
19833
|
-
const raw = `cnry_${
|
|
19834
|
-
const id =
|
|
19925
|
+
const raw = `cnry_${crypto27.randomBytes(24).toString("hex")}`;
|
|
19926
|
+
const id = crypto27.randomUUID();
|
|
19835
19927
|
db.insert(apiKeys).values({
|
|
19836
19928
|
id,
|
|
19837
19929
|
name: `${VIEWER_AERO_KEY_PREFIX}${userId}`,
|
|
@@ -19983,15 +20075,15 @@ var ViewerAeroSessions = class {
|
|
|
19983
20075
|
};
|
|
19984
20076
|
|
|
19985
20077
|
// src/mcp-http.ts
|
|
19986
|
-
import
|
|
20078
|
+
import crypto28 from "crypto";
|
|
19987
20079
|
import { eq as eq26 } from "drizzle-orm";
|
|
19988
20080
|
import { StreamableHTTPServerTransport } from "@modelcontextprotocol/sdk/server/streamableHttp.js";
|
|
19989
20081
|
import { isInitializeRequest } from "@modelcontextprotocol/sdk/types.js";
|
|
19990
20082
|
var SESSION_IDLE_MS = 10 * 60 * 1e3;
|
|
19991
20083
|
var SWEEP_INTERVAL_MS = 60 * 1e3;
|
|
19992
20084
|
function mintSessionKey(db, scopes, userId) {
|
|
19993
|
-
const raw = `cnry_${
|
|
19994
|
-
const id =
|
|
20085
|
+
const raw = `cnry_${crypto28.randomBytes(24).toString("hex")}`;
|
|
20086
|
+
const id = crypto28.randomUUID();
|
|
19995
20087
|
db.insert(apiKeys).values({
|
|
19996
20088
|
id,
|
|
19997
20089
|
name: `mcp-session:${userId}`,
|
|
@@ -20075,7 +20167,7 @@ function registerMcpHttpRoutes(scope, opts) {
|
|
|
20075
20167
|
clientName: `canonry-mcp/${PACKAGE_VERSION}`,
|
|
20076
20168
|
surface: "mcp-http",
|
|
20077
20169
|
// Correlation only: this is never accepted as caller identity or authority.
|
|
20078
|
-
actorSession:
|
|
20170
|
+
actorSession: crypto28.randomUUID()
|
|
20079
20171
|
});
|
|
20080
20172
|
let server;
|
|
20081
20173
|
try {
|
|
@@ -20092,7 +20184,7 @@ function registerMcpHttpRoutes(scope, opts) {
|
|
|
20092
20184
|
throw error;
|
|
20093
20185
|
}
|
|
20094
20186
|
const transport = new StreamableHTTPServerTransport({
|
|
20095
|
-
sessionIdGenerator: () =>
|
|
20187
|
+
sessionIdGenerator: () => crypto28.randomUUID(),
|
|
20096
20188
|
onsessioninitialized: (id) => {
|
|
20097
20189
|
sessions.set(id, { transport, close, authorizationId, segmentId: segment.id, lastSeenAt: now() });
|
|
20098
20190
|
}
|
|
@@ -21801,14 +21893,14 @@ function summarizeProviderConfig(config) {
|
|
|
21801
21893
|
};
|
|
21802
21894
|
}
|
|
21803
21895
|
function hashApiKey2(key) {
|
|
21804
|
-
return
|
|
21896
|
+
return crypto29.createHash("sha256").update(key).digest("hex");
|
|
21805
21897
|
}
|
|
21806
21898
|
var DASHBOARD_SCRYPT_KEYLEN = 64;
|
|
21807
21899
|
var DASHBOARD_SCRYPT_COST = 1 << 15;
|
|
21808
21900
|
var DASHBOARD_SCRYPT_MAXMEM = 64 * 1024 * 1024;
|
|
21809
21901
|
function hashDashboardPassword(password) {
|
|
21810
|
-
const salt =
|
|
21811
|
-
const derived =
|
|
21902
|
+
const salt = crypto29.randomBytes(16);
|
|
21903
|
+
const derived = crypto29.scryptSync(password, salt, DASHBOARD_SCRYPT_KEYLEN, {
|
|
21812
21904
|
N: DASHBOARD_SCRYPT_COST,
|
|
21813
21905
|
maxmem: DASHBOARD_SCRYPT_MAXMEM
|
|
21814
21906
|
});
|
|
@@ -21829,14 +21921,14 @@ function verifyDashboardPassword(password, storedHash) {
|
|
|
21829
21921
|
} catch {
|
|
21830
21922
|
return { ok: false, needsRehash: false };
|
|
21831
21923
|
}
|
|
21832
|
-
const derived =
|
|
21924
|
+
const derived = crypto29.scryptSync(password, salt, expected.length, {
|
|
21833
21925
|
N: DASHBOARD_SCRYPT_COST,
|
|
21834
21926
|
maxmem: DASHBOARD_SCRYPT_MAXMEM
|
|
21835
21927
|
});
|
|
21836
21928
|
if (derived.length !== expected.length)
|
|
21837
21929
|
return { ok: false, needsRehash: false };
|
|
21838
21930
|
return {
|
|
21839
|
-
ok:
|
|
21931
|
+
ok: crypto29.timingSafeEqual(derived, expected),
|
|
21840
21932
|
needsRehash: false
|
|
21841
21933
|
};
|
|
21842
21934
|
}
|
|
@@ -21845,7 +21937,7 @@ function verifyDashboardPassword(password, storedHash) {
|
|
|
21845
21937
|
const expected = Buffer.from(storedHash, "hex");
|
|
21846
21938
|
if (candidate.length !== expected.length)
|
|
21847
21939
|
return { ok: false, needsRehash: false };
|
|
21848
|
-
const ok =
|
|
21940
|
+
const ok = crypto29.timingSafeEqual(candidate, expected);
|
|
21849
21941
|
return { ok, needsRehash: ok };
|
|
21850
21942
|
}
|
|
21851
21943
|
return { ok: false, needsRehash: false };
|
|
@@ -21981,7 +22073,7 @@ function cloneGtmConfig(config) {
|
|
|
21981
22073
|
function createGoogleMarketingConfigCredentialStore(input) {
|
|
21982
22074
|
const persistConfigPatch = input.saveConfigPatch ?? saveConfigPatch;
|
|
21983
22075
|
const env = input.env ?? process.env;
|
|
21984
|
-
const randomUUID3 = input.randomUUID ??
|
|
22076
|
+
const randomUUID3 = input.randomUUID ?? crypto29.randomUUID;
|
|
21985
22077
|
const snapshot = () => ({
|
|
21986
22078
|
googleAds: cloneGoogleAdsConfig(input.config.googleAds),
|
|
21987
22079
|
gtm: cloneGtmConfig(input.config.gtm)
|
|
@@ -22084,7 +22176,7 @@ async function createServer(opts) {
|
|
|
22084
22176
|
const trustProxy = resolveTrustProxy(process.env.CANONRY_TRUST_PROXY);
|
|
22085
22177
|
const app = Fastify({
|
|
22086
22178
|
loggerInstance: logger,
|
|
22087
|
-
genReqId: () =>
|
|
22179
|
+
genReqId: () => crypto29.randomUUID(),
|
|
22088
22180
|
trustProxy
|
|
22089
22181
|
});
|
|
22090
22182
|
const registry = new ProviderRegistry();
|
|
@@ -22851,7 +22943,7 @@ async function createServer(opts) {
|
|
|
22851
22943
|
return removed;
|
|
22852
22944
|
}
|
|
22853
22945
|
};
|
|
22854
|
-
const googleStateSecret = process.env.GOOGLE_STATE_SECRET ??
|
|
22946
|
+
const googleStateSecret = process.env.GOOGLE_STATE_SECRET ?? crypto29.randomBytes(32).toString("hex");
|
|
22855
22947
|
const googleConnectionStore = {
|
|
22856
22948
|
listConnections: (domain) => listGoogleConnections(opts.config, domain),
|
|
22857
22949
|
getConnection: (domain, connectionType) => getGoogleConnection(opts.config, domain, connectionType),
|
|
@@ -22945,7 +23037,7 @@ async function createServer(opts) {
|
|
|
22945
23037
|
if (!existing) {
|
|
22946
23038
|
const prefix = opts.config.apiKey.slice(0, 12);
|
|
22947
23039
|
opts.db.insert(apiKeys).values({
|
|
22948
|
-
id: `key_${
|
|
23040
|
+
id: `key_${crypto29.randomBytes(8).toString("hex")}`,
|
|
22949
23041
|
name: "default",
|
|
22950
23042
|
keyHash,
|
|
22951
23043
|
keyPrefix: prefix,
|
|
@@ -22969,7 +23061,7 @@ async function createServer(opts) {
|
|
|
22969
23061
|
};
|
|
22970
23062
|
const createSession = (apiKeyId) => {
|
|
22971
23063
|
pruneExpiredSessions();
|
|
22972
|
-
const sessionId =
|
|
23064
|
+
const sessionId = crypto29.randomBytes(32).toString("hex");
|
|
22973
23065
|
sessions.set(sessionId, {
|
|
22974
23066
|
apiKeyId,
|
|
22975
23067
|
expiresAt: Date.now() + SESSION_TTL_MS
|
|
@@ -23442,7 +23534,7 @@ async function createServer(opts) {
|
|
|
23442
23534
|
deps: {
|
|
23443
23535
|
enqueueAutoExtract: ({ projectId, release: r }) => {
|
|
23444
23536
|
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
23445
|
-
const runId =
|
|
23537
|
+
const runId = crypto29.randomUUID();
|
|
23446
23538
|
opts.db.insert(runs).values({
|
|
23447
23539
|
id: runId,
|
|
23448
23540
|
projectId,
|
|
@@ -23686,7 +23778,7 @@ async function createServer(opts) {
|
|
|
23686
23778
|
const createdAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
23687
23779
|
opts.db.insert(auditLog).values(
|
|
23688
23780
|
targetProjectIds.map((projectId) => ({
|
|
23689
|
-
id:
|
|
23781
|
+
id: crypto29.randomUUID(),
|
|
23690
23782
|
projectId,
|
|
23691
23783
|
actor: auditContext?.actor ?? "api",
|
|
23692
23784
|
userAgent: auditContext?.userAgent ?? null,
|
|
@@ -23783,6 +23875,7 @@ async function createServer(opts) {
|
|
|
23783
23875
|
const { event: eventName, eventId, ...properties } = event;
|
|
23784
23876
|
trackEvent(eventName, properties, { source: "dashboard", eventId });
|
|
23785
23877
|
},
|
|
23878
|
+
submitFeedback: (submission, context) => sendFeedback(submission, context),
|
|
23786
23879
|
onCdpConfigure: async (host, port2) => {
|
|
23787
23880
|
if (!opts.config.cdp) opts.config.cdp = {};
|
|
23788
23881
|
opts.config.cdp.host = host;
|