@canonry/canonry 4.136.2 → 4.138.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/README.md +2 -1
- package/assets/assets/{AuditHistoryPanel-DtUGiN21.js → AuditHistoryPanel-CIdoSKjP.js} +1 -1
- package/assets/assets/{BacklinksPage-BGwtmwfz.js → BacklinksPage-BYnzQLFq.js} +1 -1
- package/assets/assets/{ChartPrimitives-Df2UC1g3.js → ChartPrimitives-bx4p5MDx.js} +1 -1
- package/assets/assets/{HistoryPage-AtaMVEUx.js → HistoryPage-CjLb8TKY.js} +1 -1
- package/assets/assets/ProjectPage-C_bSGiLs.js +8 -0
- package/assets/assets/{RunRow-Cmf-5xVo.js → RunRow-D6W6D1BX.js} +1 -1
- package/assets/assets/{RunsPage-BAPy9Yri.js → RunsPage-CQT4lXFp.js} +1 -1
- package/assets/assets/{SettingsPage-BXO7WpTo.js → SettingsPage-DVQKzz6s.js} +1 -1
- package/assets/assets/{TrafficPage-IH-wiPu2.js → TrafficPage-BdocLgWw.js} +1 -1
- package/assets/assets/{TrafficSourceDetailPage-CTTN-P52.js → TrafficSourceDetailPage-CTZF_R9C.js} +1 -1
- package/assets/assets/{arrow-left-BwzAIeJ_.js → arrow-left-ClC65OiR.js} +1 -1
- package/assets/assets/extract-error-message-CsgTjzyj.js +1 -0
- package/assets/assets/index-BZgknVrZ.js +213 -0
- package/assets/assets/{index-CglduHCN.css → index-DY7GziwY.css} +1 -1
- package/assets/assets/{trash-2-C50OeBAV.js → trash-2-nr8RRH47.js} +1 -1
- package/assets/index.html +2 -2
- package/dist/{chunk-MXR3GI5L.js → chunk-3KGJ7BXW.js} +234 -16
- package/dist/{chunk-YVMQWVNY.js → chunk-GO24URVP.js} +187 -15
- package/dist/{chunk-SMFUCXHI.js → chunk-R3GAWKHM.js} +1 -1
- package/dist/{chunk-GGIRLRAY.js → chunk-RJ7OW6W6.js} +3076 -2904
- package/dist/cli.js +147 -33
- package/dist/index.d.ts +2 -0
- package/dist/index.js +4 -4
- package/dist/{intelligence-service-BD6BHTEJ.js → intelligence-service-5RJHJLYA.js} +2 -2
- package/dist/mcp.js +2 -2
- package/package.json +11 -11
- package/assets/assets/ProjectPage-OlBjxXNx.js +0 -8
- package/assets/assets/extract-error-message-BIcIoJLN.js +0 -1
- package/assets/assets/index-BPpSrJY0.js +0 -210
|
@@ -1 +1 @@
|
|
|
1
|
-
import{c as a}from"./index-
|
|
1
|
+
import{c as a}from"./index-BZgknVrZ.js";const c=[["circle",{cx:"12",cy:"12",r:"10",key:"1mglay"}],["path",{d:"m9 12 2 2 4-4",key:"dzmm74"}]],d=a("circle-check",c);const e=[["circle",{cx:"12",cy:"12",r:"10",key:"1mglay"}],["path",{d:"M9.09 9a3 3 0 0 1 5.83 1c0 2-3 3-3 3",key:"1u773s"}],["path",{d:"M12 17h.01",key:"p32p05"}]],k=a("circle-question-mark",e);const t=[["path",{d:"M12 15V3",key:"m9g1x1"}],["path",{d:"M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4",key:"ih7n3h"}],["path",{d:"m7 10 5 5 5-5",key:"brsn70"}]],s=a("download",t);const o=[["path",{d:"M15 3h6v6",key:"1q9fwt"}],["path",{d:"M10 14 21 3",key:"gplh6r"}],["path",{d:"M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6",key:"a6xqqp"}]],r=a("external-link",o);const n=[["path",{d:"M10 11v6",key:"nco0om"}],["path",{d:"M14 11v6",key:"outv1u"}],["path",{d:"M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6",key:"miytrc"}],["path",{d:"M3 6h18",key:"d0wm0j"}],["path",{d:"M8 6V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2",key:"e791ji"}]],y=a("trash-2",n);export{d as C,s as D,r as E,y as T,k as a};
|
package/assets/index.html
CHANGED
|
@@ -12,12 +12,12 @@
|
|
|
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-BZgknVrZ.js"></script>
|
|
16
16
|
<link rel="modulepreload" crossorigin href="./assets/vendor-tanstack-Be8JdV5M.js">
|
|
17
17
|
<link rel="modulepreload" crossorigin href="./assets/vendor-radix-CQ77EO2y.js">
|
|
18
18
|
<link rel="modulepreload" crossorigin href="./assets/vendor-recharts-DSxTZhaH.js">
|
|
19
19
|
<link rel="modulepreload" crossorigin href="./assets/vendor-markdown-6dwjPOKK.js">
|
|
20
|
-
<link rel="stylesheet" crossorigin href="./assets/index-
|
|
20
|
+
<link rel="stylesheet" crossorigin href="./assets/index-DY7GziwY.css">
|
|
21
21
|
</head>
|
|
22
22
|
<body>
|
|
23
23
|
<div id="root"></div>
|
|
@@ -10,7 +10,7 @@ import {
|
|
|
10
10
|
loadConfig,
|
|
11
11
|
loadConfigRaw,
|
|
12
12
|
saveConfigPatch
|
|
13
|
-
} from "./chunk-
|
|
13
|
+
} from "./chunk-R3GAWKHM.js";
|
|
14
14
|
import {
|
|
15
15
|
CC_CACHE_DIR,
|
|
16
16
|
DUCKDB_SPEC,
|
|
@@ -119,7 +119,7 @@ import {
|
|
|
119
119
|
siteAuditPages,
|
|
120
120
|
siteAuditSnapshots,
|
|
121
121
|
usageCounters
|
|
122
|
-
} from "./chunk-
|
|
122
|
+
} from "./chunk-GO24URVP.js";
|
|
123
123
|
import {
|
|
124
124
|
AGENT_MEMORY_VALUE_MAX_BYTES,
|
|
125
125
|
AGENT_PROVIDER_IDS,
|
|
@@ -129,13 +129,16 @@ import {
|
|
|
129
129
|
AdsCampaignBiddingTypes,
|
|
130
130
|
AgentProviderIds,
|
|
131
131
|
BacklinkSources,
|
|
132
|
+
CITED_URL_CAPTURE_VERSION,
|
|
132
133
|
CcReleaseSyncStatuses,
|
|
133
134
|
CodingAgents,
|
|
134
135
|
DiscoveryCompetitorTypes,
|
|
135
136
|
LLM_CAPABILITIES,
|
|
136
137
|
LlmCapabilities,
|
|
137
138
|
MemorySources,
|
|
139
|
+
ONBOARDING_FLOW_VERSION,
|
|
138
140
|
ProviderNames,
|
|
141
|
+
ROUTE_CAPABLE_CITED_URL_PROVIDERS,
|
|
139
142
|
ResearchQueryStatuses,
|
|
140
143
|
ResearchRunStatuses,
|
|
141
144
|
RunKinds,
|
|
@@ -159,18 +162,21 @@ import {
|
|
|
159
162
|
agentMemoryUpsertRequestSchema,
|
|
160
163
|
authInvalid,
|
|
161
164
|
authRequired,
|
|
165
|
+
bucketOnboardingCount,
|
|
162
166
|
buildRunErrorFromMessages,
|
|
163
167
|
classifySkillFile,
|
|
164
168
|
coerceSkillManifest,
|
|
165
169
|
computeBacklinkSummaryMetrics,
|
|
166
170
|
contentActionLabel,
|
|
167
171
|
contentBriefDtoSchema,
|
|
172
|
+
deriveCitedUrlCandidates,
|
|
168
173
|
determineAnswerMentioned,
|
|
169
174
|
dollarsToMicros,
|
|
170
175
|
effectiveBrandNames,
|
|
171
176
|
effectiveDomains,
|
|
172
177
|
embedClientConfigForRequest,
|
|
173
178
|
factorStatusFromScore,
|
|
179
|
+
filterCapturedCitedUrls,
|
|
174
180
|
formatIsoDateInTimeZone,
|
|
175
181
|
frameAncestorsHeaderValue,
|
|
176
182
|
hostMatchesAnyDomain,
|
|
@@ -180,6 +186,7 @@ import {
|
|
|
180
186
|
isBrowserProvider,
|
|
181
187
|
isGhostTelemetryEvent,
|
|
182
188
|
isRetryableHttpError,
|
|
189
|
+
isVertexGroundingRedirect,
|
|
183
190
|
mapWithConcurrency,
|
|
184
191
|
normalizeIdTokens,
|
|
185
192
|
normalizeServedModel,
|
|
@@ -199,7 +206,7 @@ import {
|
|
|
199
206
|
validationError,
|
|
200
207
|
winnabilityClassLabel,
|
|
201
208
|
withRetry
|
|
202
|
-
} from "./chunk-
|
|
209
|
+
} from "./chunk-RJ7OW6W6.js";
|
|
203
210
|
|
|
204
211
|
// src/telemetry.ts
|
|
205
212
|
import crypto from "crypto";
|
|
@@ -214,8 +221,42 @@ var ANON_ID_PATTERN = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]
|
|
|
214
221
|
function shouldDropTelemetryEvent(event, properties) {
|
|
215
222
|
return isGhostTelemetryEvent(event, properties);
|
|
216
223
|
}
|
|
224
|
+
function bucketCliCommandDuration(durationMs) {
|
|
225
|
+
const duration = Number.isFinite(durationMs) ? Math.max(0, durationMs) : 0;
|
|
226
|
+
if (duration < 1e3) return "under_1s";
|
|
227
|
+
if (duration < 1e4) return "1s_to_10s";
|
|
228
|
+
if (duration < 6e4) return "10s_to_1m";
|
|
229
|
+
if (duration < 3e5) return "1m_to_5m";
|
|
230
|
+
if (duration < 18e5) return "5m_to_30m";
|
|
231
|
+
return "30m_or_more";
|
|
232
|
+
}
|
|
233
|
+
function trackCliCommandFinished(input) {
|
|
234
|
+
trackEvent(
|
|
235
|
+
"cli.command.finished",
|
|
236
|
+
{
|
|
237
|
+
command: input.command,
|
|
238
|
+
success: input.success,
|
|
239
|
+
duration_bucket: bucketCliCommandDuration(input.durationMs),
|
|
240
|
+
...input.setupState ? { setup_state: input.setupState } : {}
|
|
241
|
+
},
|
|
242
|
+
input.errorCode ? { errorCode: input.errorCode } : void 0
|
|
243
|
+
);
|
|
244
|
+
}
|
|
217
245
|
var SESSION_ID = crypto.randomUUID();
|
|
218
246
|
var CURRENT_SOURCE = "cli";
|
|
247
|
+
var TELEMETRY_SOURCE_VALUES = /* @__PURE__ */ new Set([
|
|
248
|
+
"cli",
|
|
249
|
+
"cli-server",
|
|
250
|
+
"api",
|
|
251
|
+
"mcp-server",
|
|
252
|
+
"wp-plugin",
|
|
253
|
+
"dashboard",
|
|
254
|
+
"agent-runtime"
|
|
255
|
+
]);
|
|
256
|
+
function envSourceOverride() {
|
|
257
|
+
const raw = process.env.CANONRY_TELEMETRY_SOURCE?.trim();
|
|
258
|
+
return raw && TELEMETRY_SOURCE_VALUES.has(raw) ? raw : void 0;
|
|
259
|
+
}
|
|
219
260
|
function setTelemetrySource(source) {
|
|
220
261
|
CURRENT_SOURCE = source;
|
|
221
262
|
}
|
|
@@ -331,9 +372,10 @@ function trackEvent(event, properties, options) {
|
|
|
331
372
|
const anonymousId = getOrCreateAnonymousId();
|
|
332
373
|
if (!anonymousId) return;
|
|
333
374
|
const payload = {
|
|
375
|
+
eventId: options?.eventId ?? crypto.randomUUID(),
|
|
334
376
|
anonymousId,
|
|
335
377
|
sessionId: SESSION_ID,
|
|
336
|
-
source: options?.source ?? CURRENT_SOURCE,
|
|
378
|
+
source: options?.source ?? envSourceOverride() ?? CURRENT_SOURCE,
|
|
337
379
|
event,
|
|
338
380
|
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
339
381
|
version: VERSION,
|
|
@@ -347,13 +389,17 @@ function trackEvent(event, properties, options) {
|
|
|
347
389
|
const controller = new AbortController();
|
|
348
390
|
const timeout = setTimeout(() => controller.abort(), TIMEOUT_MS);
|
|
349
391
|
timeout.unref();
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
392
|
+
try {
|
|
393
|
+
void fetch(TELEMETRY_ENDPOINT, {
|
|
394
|
+
method: "POST",
|
|
395
|
+
headers: { "Content-Type": "application/json" },
|
|
396
|
+
body: JSON.stringify(payload),
|
|
397
|
+
signal: controller.signal
|
|
398
|
+
}).catch(() => {
|
|
399
|
+
}).finally(() => clearTimeout(timeout));
|
|
400
|
+
} catch {
|
|
401
|
+
clearTimeout(timeout);
|
|
402
|
+
}
|
|
357
403
|
}
|
|
358
404
|
|
|
359
405
|
// src/update-check.ts
|
|
@@ -3071,7 +3117,7 @@ import crypto4 from "crypto";
|
|
|
3071
3117
|
import fs2 from "fs";
|
|
3072
3118
|
import path3 from "path";
|
|
3073
3119
|
import os3 from "os";
|
|
3074
|
-
import { and as and2, eq as eq2, inArray, sql as sql2 } from "drizzle-orm";
|
|
3120
|
+
import { and as and2, eq as eq2, inArray, ne, sql as sql2 } from "drizzle-orm";
|
|
3075
3121
|
|
|
3076
3122
|
// src/run-telemetry.ts
|
|
3077
3123
|
import crypto2 from "crypto";
|
|
@@ -3205,6 +3251,87 @@ function releaseDailyQueryQuota(db, input) {
|
|
|
3205
3251
|
db.update(usageCounters).set({ count: sql`MAX(0, ${usageCounters.count} - ${input.count})`, updatedAt: (/* @__PURE__ */ new Date()).toISOString() }).where(and(eq(usageCounters.scope, input.scope), eq(usageCounters.period, input.period), eq(usageCounters.metric, "queries"))).run();
|
|
3206
3252
|
}
|
|
3207
3253
|
|
|
3254
|
+
// src/cited-url-capture.ts
|
|
3255
|
+
var RESOLUTION_CONCURRENCY = 5;
|
|
3256
|
+
var RESOLUTION_TIMEOUT_MS = 5e3;
|
|
3257
|
+
var MAX_VERTEX_PROXY_HOPS = 3;
|
|
3258
|
+
var REDIRECT_STATUSES = /* @__PURE__ */ new Set([301, 302, 303, 307, 308]);
|
|
3259
|
+
function isRouteCapableProvider(provider) {
|
|
3260
|
+
return ROUTE_CAPABLE_CITED_URL_PROVIDERS.includes(provider);
|
|
3261
|
+
}
|
|
3262
|
+
function parseHttpUrl(value, base) {
|
|
3263
|
+
try {
|
|
3264
|
+
const url = new URL(value, base);
|
|
3265
|
+
if (url.protocol !== "http:" && url.protocol !== "https:") return void 0;
|
|
3266
|
+
url.hash = "";
|
|
3267
|
+
return url;
|
|
3268
|
+
} catch {
|
|
3269
|
+
return void 0;
|
|
3270
|
+
}
|
|
3271
|
+
}
|
|
3272
|
+
async function resolveVertexGroundingRedirect(value, opts = {}) {
|
|
3273
|
+
const initial = parseHttpUrl(value);
|
|
3274
|
+
if (!initial || !isVertexGroundingRedirect(initial)) return void 0;
|
|
3275
|
+
const fetchImpl = opts.fetchImpl ?? globalThis.fetch;
|
|
3276
|
+
const timeoutMs = opts.timeoutMs ?? RESOLUTION_TIMEOUT_MS;
|
|
3277
|
+
let current = initial;
|
|
3278
|
+
for (let hop = 0; hop <= MAX_VERTEX_PROXY_HOPS; hop++) {
|
|
3279
|
+
const controller = new AbortController();
|
|
3280
|
+
const timer = setTimeout(() => controller.abort(), timeoutMs);
|
|
3281
|
+
let response;
|
|
3282
|
+
try {
|
|
3283
|
+
response = await fetchImpl(current, { redirect: "manual", signal: controller.signal });
|
|
3284
|
+
} catch {
|
|
3285
|
+
return void 0;
|
|
3286
|
+
} finally {
|
|
3287
|
+
clearTimeout(timer);
|
|
3288
|
+
}
|
|
3289
|
+
if (!REDIRECT_STATUSES.has(response.status)) return void 0;
|
|
3290
|
+
const location = response.headers.get("location");
|
|
3291
|
+
if (!location) return void 0;
|
|
3292
|
+
const next = parseHttpUrl(location, current.toString());
|
|
3293
|
+
if (!next) return void 0;
|
|
3294
|
+
if (!isVertexGroundingRedirect(next)) return next.toString();
|
|
3295
|
+
current = next;
|
|
3296
|
+
}
|
|
3297
|
+
return void 0;
|
|
3298
|
+
}
|
|
3299
|
+
async function captureCitedUrls(provider, sources, opts = {}) {
|
|
3300
|
+
const sourceCount = sources.length;
|
|
3301
|
+
if (!isRouteCapableProvider(provider)) {
|
|
3302
|
+
return {
|
|
3303
|
+
citedUrls: null,
|
|
3304
|
+
captureStatus: "unsupported",
|
|
3305
|
+
sourceCount,
|
|
3306
|
+
resolvedCount: 0,
|
|
3307
|
+
captureVersion: CITED_URL_CAPTURE_VERSION
|
|
3308
|
+
};
|
|
3309
|
+
}
|
|
3310
|
+
const candidates = deriveCitedUrlCandidates(sources);
|
|
3311
|
+
const candidateCount = candidates.length;
|
|
3312
|
+
let resolved;
|
|
3313
|
+
try {
|
|
3314
|
+
resolved = await mapWithConcurrency(candidates, RESOLUTION_CONCURRENCY, async (candidate) => {
|
|
3315
|
+
const parsed = parseHttpUrl(candidate);
|
|
3316
|
+
if (!parsed) return void 0;
|
|
3317
|
+
if (!isVertexGroundingRedirect(parsed)) return candidate;
|
|
3318
|
+
return resolveVertexGroundingRedirect(candidate, opts);
|
|
3319
|
+
});
|
|
3320
|
+
} catch {
|
|
3321
|
+
resolved = candidates.map(() => void 0);
|
|
3322
|
+
}
|
|
3323
|
+
const acceptedPerSource = resolved.map((value) => filterCapturedCitedUrls([value]).at(0));
|
|
3324
|
+
const resolvedCount = acceptedPerSource.filter((value) => value !== void 0).length;
|
|
3325
|
+
const captureStatus = resolvedCount === candidateCount ? "complete" : resolvedCount > 0 ? "partial" : "failed";
|
|
3326
|
+
return {
|
|
3327
|
+
citedUrls: filterCapturedCitedUrls(acceptedPerSource),
|
|
3328
|
+
captureStatus,
|
|
3329
|
+
sourceCount,
|
|
3330
|
+
resolvedCount,
|
|
3331
|
+
captureVersion: CITED_URL_CAPTURE_VERSION
|
|
3332
|
+
};
|
|
3333
|
+
}
|
|
3334
|
+
|
|
3208
3335
|
// src/job-runner.ts
|
|
3209
3336
|
var log = createLogger("JobRunner");
|
|
3210
3337
|
var RunCancelledError = class extends Error {
|
|
@@ -3278,10 +3405,18 @@ function classifyOneProviderError(message) {
|
|
|
3278
3405
|
return "UNKNOWN";
|
|
3279
3406
|
}
|
|
3280
3407
|
var JobRunner = class {
|
|
3408
|
+
/**
|
|
3409
|
+
* Invoked exactly when `activation.completed` is emitted: the project's
|
|
3410
|
+
* first non-empty, non-probe answer-visibility result. The serve process
|
|
3411
|
+
* uses it to thank the operator once; it is a UX hook, not telemetry, so it
|
|
3412
|
+
* fires (and is given) independently of whether telemetry is enabled.
|
|
3413
|
+
*/
|
|
3414
|
+
onFirstActivation;
|
|
3281
3415
|
db;
|
|
3282
3416
|
registry;
|
|
3283
3417
|
onRunCompleted;
|
|
3284
|
-
constructor(db, registry) {
|
|
3418
|
+
constructor(db, registry, opts) {
|
|
3419
|
+
this.onFirstActivation = opts?.onFirstActivation;
|
|
3285
3420
|
this.db = db;
|
|
3286
3421
|
this.registry = registry;
|
|
3287
3422
|
}
|
|
@@ -3420,7 +3555,31 @@ var JobRunner = class {
|
|
|
3420
3555
|
config
|
|
3421
3556
|
);
|
|
3422
3557
|
this.throwIfRunCancelled(runId);
|
|
3423
|
-
const
|
|
3558
|
+
const providerResult = adapter.normalizeResult(raw);
|
|
3559
|
+
const rawGroundingSources = providerResult.groundingSources;
|
|
3560
|
+
const normalized = {
|
|
3561
|
+
...providerResult,
|
|
3562
|
+
groundingSources: Array.isArray(rawGroundingSources) ? rawGroundingSources : []
|
|
3563
|
+
};
|
|
3564
|
+
let citedUrlCapture;
|
|
3565
|
+
try {
|
|
3566
|
+
citedUrlCapture = await captureCitedUrls(providerName, rawGroundingSources);
|
|
3567
|
+
} catch (err) {
|
|
3568
|
+
citedUrlCapture = {
|
|
3569
|
+
citedUrls: [],
|
|
3570
|
+
captureStatus: "failed",
|
|
3571
|
+
sourceCount: normalized.groundingSources.length,
|
|
3572
|
+
resolvedCount: 0,
|
|
3573
|
+
captureVersion: CITED_URL_CAPTURE_VERSION
|
|
3574
|
+
};
|
|
3575
|
+
log.warn("query.cited-url-capture-failed", {
|
|
3576
|
+
runId,
|
|
3577
|
+
provider: providerName,
|
|
3578
|
+
query: q.query,
|
|
3579
|
+
error: err instanceof Error ? err.message : String(err)
|
|
3580
|
+
});
|
|
3581
|
+
}
|
|
3582
|
+
this.throwIfRunCancelled(runId);
|
|
3424
3583
|
log.info("query.result", { runId, provider: providerName, query: q.query, citedDomains: normalized.citedDomains, groundingSources: normalized.groundingSources.map((s) => s.uri), matchDomains: allDomains });
|
|
3425
3584
|
const citationState = determineCitationState(normalized, allDomains);
|
|
3426
3585
|
const answerMentioned = determineAnswerMentioned(
|
|
@@ -3456,6 +3615,11 @@ var JobRunner = class {
|
|
|
3456
3615
|
answerMentioned,
|
|
3457
3616
|
answerText: normalized.answerText,
|
|
3458
3617
|
citedDomains: normalized.citedDomains,
|
|
3618
|
+
citedUrls: citedUrlCapture.citedUrls,
|
|
3619
|
+
captureStatus: citedUrlCapture.captureStatus,
|
|
3620
|
+
sourceCount: citedUrlCapture.sourceCount,
|
|
3621
|
+
resolvedCount: citedUrlCapture.resolvedCount,
|
|
3622
|
+
captureVersion: citedUrlCapture.captureVersion,
|
|
3459
3623
|
competitorOverlap: overlap,
|
|
3460
3624
|
recommendedCompetitors: extractedCompetitors,
|
|
3461
3625
|
location: runLocation?.label ?? null,
|
|
@@ -3482,6 +3646,11 @@ var JobRunner = class {
|
|
|
3482
3646
|
answerMentioned,
|
|
3483
3647
|
answerText: normalized.answerText,
|
|
3484
3648
|
citedDomains: normalized.citedDomains,
|
|
3649
|
+
citedUrls: citedUrlCapture.citedUrls,
|
|
3650
|
+
captureStatus: citedUrlCapture.captureStatus,
|
|
3651
|
+
sourceCount: citedUrlCapture.sourceCount,
|
|
3652
|
+
resolvedCount: citedUrlCapture.resolvedCount,
|
|
3653
|
+
captureVersion: citedUrlCapture.captureVersion,
|
|
3485
3654
|
competitorOverlap: overlap,
|
|
3486
3655
|
recommendedCompetitors: extractedCompetitors,
|
|
3487
3656
|
location: runLocation?.label ?? null,
|
|
@@ -3553,6 +3722,19 @@ var JobRunner = class {
|
|
|
3553
3722
|
}),
|
|
3554
3723
|
failureCode ? { errorCode: failureCode } : void 0
|
|
3555
3724
|
);
|
|
3725
|
+
if (existingRun.kind === "answer-visibility" && runTrigger !== "probe" && totalSnapshotsInserted > 0 && !this.hasPriorActivation(projectId, runId)) {
|
|
3726
|
+
trackEvent("activation.completed", {
|
|
3727
|
+
flowVersion: ONBOARDING_FLOW_VERSION,
|
|
3728
|
+
status: finalStatus,
|
|
3729
|
+
providerCountBucket: bucketOnboardingCount(executionContext.providerCount),
|
|
3730
|
+
queryCountBucket: bucketOnboardingCount(executionContext.queryCount),
|
|
3731
|
+
snapshotCountBucket: bucketOnboardingCount(totalSnapshotsInserted)
|
|
3732
|
+
});
|
|
3733
|
+
try {
|
|
3734
|
+
this.onFirstActivation?.();
|
|
3735
|
+
} catch {
|
|
3736
|
+
}
|
|
3737
|
+
}
|
|
3556
3738
|
this.incrementUsage(projectId, "runs", 1);
|
|
3557
3739
|
if (this.onRunCompleted) {
|
|
3558
3740
|
this.onRunCompleted(runId, projectId).catch((err) => {
|
|
@@ -3641,8 +3823,18 @@ var JobRunner = class {
|
|
|
3641
3823
|
}
|
|
3642
3824
|
providerReservations.clear();
|
|
3643
3825
|
}
|
|
3826
|
+
hasPriorActivation(projectId, currentRunId) {
|
|
3827
|
+
return this.db.select({ id: querySnapshots.id }).from(querySnapshots).innerJoin(runs, eq2(querySnapshots.runId, runs.id)).where(and2(
|
|
3828
|
+
eq2(runs.projectId, projectId),
|
|
3829
|
+
eq2(runs.kind, "answer-visibility"),
|
|
3830
|
+
inArray(runs.status, ["completed", "partial"]),
|
|
3831
|
+
ne(runs.trigger, "probe"),
|
|
3832
|
+
ne(runs.id, currentRunId)
|
|
3833
|
+
)).limit(1).get() !== void 0;
|
|
3834
|
+
}
|
|
3644
3835
|
getRunState(runId) {
|
|
3645
3836
|
return this.db.select({
|
|
3837
|
+
kind: runs.kind,
|
|
3646
3838
|
status: runs.status,
|
|
3647
3839
|
finishedAt: runs.finishedAt,
|
|
3648
3840
|
error: runs.error,
|
|
@@ -3697,6 +3889,21 @@ function buildPhases(input) {
|
|
|
3697
3889
|
return { setup_ms, provider_call_ms, total_ms };
|
|
3698
3890
|
}
|
|
3699
3891
|
|
|
3892
|
+
// src/activation-notice.ts
|
|
3893
|
+
var ACTIVATION_NOTICE = "\n\u2605 First sweep finished. Your AI visibility baseline is in the dashboard.\n If Canonry is useful, a GitHub star helps others find it:\n https://github.com/Canonry/canonry\n\n";
|
|
3894
|
+
function maybeShowActivationNotice(io = {}) {
|
|
3895
|
+
const isTTY = io.isTTY ?? Boolean(process.stderr.isTTY);
|
|
3896
|
+
const write = io.write ?? ((line) => process.stderr.write(line));
|
|
3897
|
+
try {
|
|
3898
|
+
if (!isTTY) return;
|
|
3899
|
+
const raw = loadConfigRaw();
|
|
3900
|
+
if (!raw || raw.activationNoticeShown === true) return;
|
|
3901
|
+
saveConfigPatch({ activationNoticeShown: true });
|
|
3902
|
+
write(ACTIVATION_NOTICE);
|
|
3903
|
+
} catch {
|
|
3904
|
+
}
|
|
3905
|
+
}
|
|
3906
|
+
|
|
3700
3907
|
// src/gsc-sync.ts
|
|
3701
3908
|
import crypto5 from "crypto";
|
|
3702
3909
|
import { eq as eq3, and as and3, sql as sql3 } from "drizzle-orm";
|
|
@@ -7032,7 +7239,7 @@ function readStoredGroundingSources(rawResponse) {
|
|
|
7032
7239
|
return result;
|
|
7033
7240
|
}
|
|
7034
7241
|
async function backfillInsightsCommand(project, opts) {
|
|
7035
|
-
const { IntelligenceService: IntelligenceService2 } = await import("./intelligence-service-
|
|
7242
|
+
const { IntelligenceService: IntelligenceService2 } = await import("./intelligence-service-5RJHJLYA.js");
|
|
7036
7243
|
const config = loadConfig();
|
|
7037
7244
|
const db = createClient(config.database);
|
|
7038
7245
|
migrate(db);
|
|
@@ -11930,7 +12137,12 @@ async function createServer(opts) {
|
|
|
11930
12137
|
}
|
|
11931
12138
|
const port = opts.config.port ?? 4100;
|
|
11932
12139
|
const serverUrl = `http://localhost:${port}`;
|
|
11933
|
-
const jobRunner = new JobRunner(opts.db, registry
|
|
12140
|
+
const jobRunner = new JobRunner(opts.db, registry, {
|
|
12141
|
+
// The one-time first-sweep thank-you. Lives on the serve console because
|
|
12142
|
+
// runs execute here, including the foreground serve that init hands off
|
|
12143
|
+
// to. TTY-gated inside, so supervised deployments never see it.
|
|
12144
|
+
onFirstActivation: () => maybeShowActivationNotice()
|
|
12145
|
+
});
|
|
11934
12146
|
jobRunner.recoverStaleRuns();
|
|
11935
12147
|
const notifier = new Notifier(opts.db, serverUrl);
|
|
11936
12148
|
const intelligenceService = new IntelligenceService(opts.db);
|
|
@@ -13059,6 +13271,7 @@ async function createServer(opts) {
|
|
|
13059
13271
|
app.log.error({ runId, err }, "Job runner failed");
|
|
13060
13272
|
});
|
|
13061
13273
|
},
|
|
13274
|
+
getRunnableProviderNames: () => registry.getAll().map((provider) => provider.adapter.name),
|
|
13062
13275
|
onProviderUpdate: (providerName, apiKey, model, baseUrl, incomingQuota) => {
|
|
13063
13276
|
const name = providerName;
|
|
13064
13277
|
if (!adapterMap[name]) return null;
|
|
@@ -13196,6 +13409,10 @@ async function createServer(opts) {
|
|
|
13196
13409
|
saveConfigPatch(config);
|
|
13197
13410
|
opts.config.telemetry = enabled;
|
|
13198
13411
|
},
|
|
13412
|
+
recordOnboardingEvent: (event) => {
|
|
13413
|
+
const { event: eventName, eventId, ...properties } = event;
|
|
13414
|
+
trackEvent(eventName, properties, { source: "dashboard", eventId });
|
|
13415
|
+
},
|
|
13199
13416
|
onCdpConfigure: async (host, port2) => {
|
|
13200
13417
|
if (!opts.config.cdp) opts.config.cdp = {};
|
|
13201
13418
|
opts.config.cdp.host = host;
|
|
@@ -13434,6 +13651,7 @@ function parseQueryResponse(raw, count) {
|
|
|
13434
13651
|
}
|
|
13435
13652
|
|
|
13436
13653
|
export {
|
|
13654
|
+
trackCliCommandFinished,
|
|
13437
13655
|
setTelemetrySource,
|
|
13438
13656
|
isTelemetryEnabled,
|
|
13439
13657
|
getOrCreateAnonymousId,
|