@canonry/canonry 7.19.0 → 7.20.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/assets/agent-workspace/skills/aero/references/agent-operations.md +14 -0
- package/assets/agent-workspace/skills/canonry/SKILL.md +14 -0
- package/assets/agent-workspace/skills/canonry/references/canonry-cli.md +33 -1
- package/assets/assets/{AuditHistoryPanel-DEEWm-4t.js → AuditHistoryPanel-DVtz1ZuT.js} +1 -1
- package/assets/assets/{BacklinksPage-F5QBgXbF.js → BacklinksPage-Tvt0-ppX.js} +1 -1
- package/assets/assets/{HistoryPage-CNp42sUO.js → HistoryPage-DqXwPH3k.js} +1 -1
- package/assets/assets/{MeasurementPropertyPage-XpI9hVMb.js → MeasurementPropertyPage-CsbfFEjB.js} +1 -1
- package/assets/assets/{ProjectPage-B_V4QpyI.js → ProjectPage-Cyvt96AV.js} +2 -2
- package/assets/assets/{RunsPage-PTHloZl3.js → RunsPage-Io7ZFw4-.js} +1 -1
- package/assets/assets/{SettingsPage-C-aDo2zf.js → SettingsPage-BPYxgchP.js} +1 -1
- package/assets/assets/{SiteHealthSection-DvoT8IuX.js → SiteHealthSection-CwffU3tv.js} +3 -3
- package/assets/assets/{TrafficPage-DahJoMKF.js → TrafficPage-DIm60m1J.js} +1 -1
- package/assets/assets/{TrafficSourceDetailPage-BGlHXOlk.js → TrafficSourceDetailPage-DWT1Ip5P.js} +1 -1
- package/assets/assets/{extract-error-message-CP_fyJLM.js → extract-error-message-BVYchXhT.js} +1 -1
- package/assets/assets/{index-C5V8xlr0.js → index-DrQLR1jE.js} +20 -20
- package/assets/assets/{react-sigma_core.esm.min-DUS8srfg.js → react-sigma_core.esm.min-f31sqfAC.js} +1 -1
- package/assets/assets/{v2-overview-adapter-ycJ1guZb.js → v2-overview-adapter-By0930UY.js} +1 -1
- package/assets/index.html +1 -1
- package/dist/{chunk-A75L7CUV.js → chunk-222NAFTY.js} +2 -2
- package/dist/{chunk-UUI4HOEL.js → chunk-46JZR2IV.js} +46 -8
- package/dist/{chunk-VSTKTQPS.js → chunk-5IXQAOVK.js} +16 -1
- package/dist/{chunk-PBTTPZZE.js → chunk-6H2BC5EY.js} +3 -3
- package/dist/{chunk-OMP5OLBK.js → chunk-CIPWGVX6.js} +368 -211
- package/dist/{chunk-CYHUZ2JQ.js → chunk-MRKV43TV.js} +19 -0
- package/dist/{chunk-35IIFDIT.js → chunk-NDQOCFJQ.js} +61 -43
- package/dist/cli.js +213 -39
- package/dist/{demo-server-K5G54GOE.js → demo-server-32PU7BM6.js} +4 -4
- package/dist/index.d.ts +1 -1
- package/dist/index.js +6 -6
- package/dist/{intelligence-service-LV2TQMMR.js → intelligence-service-256DQBVR.js} +2 -2
- package/dist/mcp.js +4 -4
- package/package.json +12 -12
package/dist/cli.js
CHANGED
|
@@ -21,6 +21,7 @@ import {
|
|
|
21
21
|
listAgentProviders,
|
|
22
22
|
notePrintedUpdateAvailable,
|
|
23
23
|
readCachedUpdateAvailable,
|
|
24
|
+
registeredProviderNames,
|
|
24
25
|
reparseStoredResult,
|
|
25
26
|
reparseStoredResult2,
|
|
26
27
|
reparseStoredResult3,
|
|
@@ -34,11 +35,11 @@ import {
|
|
|
34
35
|
trackCliCommandFinished,
|
|
35
36
|
trackEvent,
|
|
36
37
|
waitForServerRuntimeStartup
|
|
37
|
-
} from "./chunk-
|
|
38
|
+
} from "./chunk-CIPWGVX6.js";
|
|
38
39
|
import {
|
|
39
40
|
autoSyncSkills,
|
|
40
41
|
formatAutoSyncNotice
|
|
41
|
-
} from "./chunk-
|
|
42
|
+
} from "./chunk-6H2BC5EY.js";
|
|
42
43
|
import {
|
|
43
44
|
configExists,
|
|
44
45
|
createApiClient,
|
|
@@ -54,14 +55,15 @@ import {
|
|
|
54
55
|
parseSkillsClient,
|
|
55
56
|
saveConfig,
|
|
56
57
|
saveConfigPatch,
|
|
57
|
-
shouldPrintServeSkillsNudge
|
|
58
|
-
|
|
58
|
+
shouldPrintServeSkillsNudge,
|
|
59
|
+
withBootstrapProviderDefaults
|
|
60
|
+
} from "./chunk-NDQOCFJQ.js";
|
|
59
61
|
import {
|
|
60
62
|
DEFAULT_DEMO_TRUSTED_PROXIES,
|
|
61
63
|
trustedProxiesProblem,
|
|
62
64
|
trustedProxyProblem
|
|
63
65
|
} from "./chunk-RB2F4D3Z.js";
|
|
64
|
-
import "./chunk-
|
|
66
|
+
import "./chunk-222NAFTY.js";
|
|
65
67
|
import {
|
|
66
68
|
CliError,
|
|
67
69
|
EXIT_SYSTEM_ERROR,
|
|
@@ -73,7 +75,7 @@ import {
|
|
|
73
75
|
runMeasurementDraftAction,
|
|
74
76
|
systemError,
|
|
75
77
|
usageError
|
|
76
|
-
} from "./chunk-
|
|
78
|
+
} from "./chunk-5IXQAOVK.js";
|
|
77
79
|
import {
|
|
78
80
|
CLOUDFLARE_WORKER_BINDINGS,
|
|
79
81
|
CLOUDFLARE_WORKER_GENERATED_MARKER,
|
|
@@ -105,7 +107,7 @@ import {
|
|
|
105
107
|
rawEventSamples,
|
|
106
108
|
readMarketCompetitorNames,
|
|
107
109
|
runs
|
|
108
|
-
} from "./chunk-
|
|
110
|
+
} from "./chunk-46JZR2IV.js";
|
|
109
111
|
import {
|
|
110
112
|
AdsDeliverySnapshotStatuses,
|
|
111
113
|
AdsHistoricalCampaignRollupStatuses,
|
|
@@ -126,6 +128,7 @@ import {
|
|
|
126
128
|
OUTSTANDING_PROVIDER_BATCH_STATUSES,
|
|
127
129
|
ProviderBatchStatuses,
|
|
128
130
|
ProviderNames,
|
|
131
|
+
ProviderReloadErrorReasons,
|
|
129
132
|
READ_ONLY_SCOPE,
|
|
130
133
|
RatioUnits,
|
|
131
134
|
ResearchRunStatuses,
|
|
@@ -238,7 +241,7 @@ import {
|
|
|
238
241
|
visibilityCompareSelectionSchema,
|
|
239
242
|
visibilityReportRequestSchema,
|
|
240
243
|
winnabilityClassSchema
|
|
241
|
-
} from "./chunk-
|
|
244
|
+
} from "./chunk-MRKV43TV.js";
|
|
242
245
|
|
|
243
246
|
// src/cli.ts
|
|
244
247
|
import { pathToFileURL } from "url";
|
|
@@ -256,11 +259,7 @@ function buildSetupState() {
|
|
|
256
259
|
const raw = loadConfigRaw();
|
|
257
260
|
if (raw) {
|
|
258
261
|
is_first_run = !raw.anonymousId;
|
|
259
|
-
|
|
260
|
-
provider_count = Object.values(raw.providers).filter(
|
|
261
|
-
(p) => Boolean(p?.apiKey) || Boolean(p?.baseUrl)
|
|
262
|
-
).length;
|
|
263
|
-
}
|
|
262
|
+
provider_count = registeredProviderNames(raw).length;
|
|
264
263
|
if (typeof raw.database === "string" && raw.database.length > 0) {
|
|
265
264
|
dbPath = raw.database;
|
|
266
265
|
}
|
|
@@ -788,7 +787,7 @@ function parseDemoTrustedProxies(values) {
|
|
|
788
787
|
async function demoCommand(options) {
|
|
789
788
|
const { host, port } = parseDemoListenOptions(options);
|
|
790
789
|
const trustProxy = parseDemoTrustedProxies(options.trustProxy);
|
|
791
|
-
const { createDemoServer } = await import("./demo-server-
|
|
790
|
+
const { createDemoServer } = await import("./demo-server-32PU7BM6.js");
|
|
792
791
|
const app = await createDemoServer({ trustProxy });
|
|
793
792
|
let stopping = false;
|
|
794
793
|
const stop = () => {
|
|
@@ -1202,7 +1201,7 @@ No DB writes performed. Re-run without --dry-run to apply.`);
|
|
|
1202
1201
|
}
|
|
1203
1202
|
}
|
|
1204
1203
|
async function backfillInsightsCommand(project2, opts) {
|
|
1205
|
-
const { IntelligenceService } = await import("./intelligence-service-
|
|
1204
|
+
const { IntelligenceService } = await import("./intelligence-service-256DQBVR.js");
|
|
1206
1205
|
const config = loadConfig();
|
|
1207
1206
|
const db = createClient(config.database);
|
|
1208
1207
|
migrate(db);
|
|
@@ -15617,6 +15616,17 @@ async function showSettings(format) {
|
|
|
15617
15616
|
console.log("\nGoogle OAuth:\n");
|
|
15618
15617
|
console.log(` ${settings.google.configured ? "configured" : "not configured"}`);
|
|
15619
15618
|
}
|
|
15619
|
+
async function reloadProviders(format) {
|
|
15620
|
+
const result = await getClient25().reloadProviders();
|
|
15621
|
+
if (isMachineFormat(format)) {
|
|
15622
|
+
console.log(JSON.stringify(result, null, 2));
|
|
15623
|
+
return;
|
|
15624
|
+
}
|
|
15625
|
+
console.log("Saved provider configuration is now active on the server.");
|
|
15626
|
+
for (const provider of result.providers) {
|
|
15627
|
+
console.log(` ${provider.name}: ${provider.configured ? "configured" : "not configured"}`);
|
|
15628
|
+
}
|
|
15629
|
+
}
|
|
15620
15630
|
async function setGoogleAuth(opts) {
|
|
15621
15631
|
if (opts.target === "server") {
|
|
15622
15632
|
const result = await getClient25().updateGoogleSettings({
|
|
@@ -15650,6 +15660,11 @@ async function setGoogleAuth(opts) {
|
|
|
15650
15660
|
|
|
15651
15661
|
// src/cli-commands/settings.ts
|
|
15652
15662
|
var SETTINGS_CLI_COMMANDS = [
|
|
15663
|
+
{
|
|
15664
|
+
path: ["settings", "reload-providers"],
|
|
15665
|
+
usage: "canonry settings reload-providers [--format json]",
|
|
15666
|
+
run: async (input) => reloadProviders(input.format)
|
|
15667
|
+
},
|
|
15653
15668
|
{
|
|
15654
15669
|
path: ["settings", "provider"],
|
|
15655
15670
|
usage: "canonry settings provider <name> [--api-key <key>] [--base-url <url>] [--model <model>] [--max-concurrent <n>] [--max-per-minute <n>] [--max-per-day <n>] [--format json]",
|
|
@@ -15777,7 +15792,7 @@ Usage: canonry settings provider ${name} --api-key <key> [--model <model>] [--ma
|
|
|
15777
15792
|
},
|
|
15778
15793
|
{
|
|
15779
15794
|
path: ["settings"],
|
|
15780
|
-
usage: "canonry settings [provider|google] [args]",
|
|
15795
|
+
usage: "canonry settings [provider|reload-providers|google] [args]",
|
|
15781
15796
|
run: async (input) => {
|
|
15782
15797
|
const subcommand = input.positionals[0];
|
|
15783
15798
|
if (!subcommand) {
|
|
@@ -15786,8 +15801,8 @@ Usage: canonry settings provider ${name} --api-key <key> [--model <model>] [--ma
|
|
|
15786
15801
|
}
|
|
15787
15802
|
unknownSubcommand(subcommand, {
|
|
15788
15803
|
command: "settings",
|
|
15789
|
-
usage: "canonry settings [provider|google] [args]",
|
|
15790
|
-
available: ["provider", "google"]
|
|
15804
|
+
usage: "canonry settings [provider|reload-providers|google] [args]",
|
|
15805
|
+
available: ["provider", "reload-providers", "google"]
|
|
15791
15806
|
});
|
|
15792
15807
|
}
|
|
15793
15808
|
}
|
|
@@ -17301,14 +17316,72 @@ function persistedValue(value) {
|
|
|
17301
17316
|
}
|
|
17302
17317
|
return value;
|
|
17303
17318
|
}
|
|
17319
|
+
var PROVIDER_FREE_NEXT_STEPS = [
|
|
17320
|
+
"AI Visibility needs an answer-engine provider. Page Health does not.",
|
|
17321
|
+
"With the server running, the operator runs `canonry settings provider gemini --api-key <key>` (free key at https://aistudio.google.com/apikey). It takes effect immediately.",
|
|
17322
|
+
"Or the operator sets GEMINI_API_KEY and reruns `canonry bootstrap`. It reloads the matching running local server and confirms active providers; an offline server uses the saved settings at startup.",
|
|
17323
|
+
"A provider key is the operator's credential: never ask for it in chat."
|
|
17324
|
+
];
|
|
17325
|
+
var PROVIDER_CREDENTIAL_FIELDS = {
|
|
17326
|
+
[ProviderNames.gemini]: ["apiKey", "vertexProject", "vertexRegion", "vertexCredentials"],
|
|
17327
|
+
// A local key belongs to the server at its base URL.
|
|
17328
|
+
[ProviderNames.local]: ["baseUrl", "apiKey"]
|
|
17329
|
+
};
|
|
17330
|
+
var API_KEY_CREDENTIAL_FIELDS = ["apiKey"];
|
|
17331
|
+
function mergeEnvProvider(name, saved, fromEnv) {
|
|
17332
|
+
const credentialFields = PROVIDER_CREDENTIAL_FIELDS[name] ?? API_KEY_CREDENTIAL_FIELDS;
|
|
17333
|
+
const envFields = Object.entries(fromEnv);
|
|
17334
|
+
const envValues = new Map(envFields);
|
|
17335
|
+
const merged = {};
|
|
17336
|
+
for (const [field, value] of Object.entries(saved ?? {})) {
|
|
17337
|
+
if (envValues.get(field) !== void 0) merged[field] = envValues.get(field);
|
|
17338
|
+
else if (!credentialFields.includes(field)) merged[field] = value;
|
|
17339
|
+
}
|
|
17340
|
+
for (const [field, value] of envFields) {
|
|
17341
|
+
if (!(field in merged)) merged[field] = value;
|
|
17342
|
+
}
|
|
17343
|
+
return withBootstrapProviderDefaults(name, merged);
|
|
17344
|
+
}
|
|
17345
|
+
var ServerReloadStatuses = {
|
|
17346
|
+
reloaded: "reloaded",
|
|
17347
|
+
unchanged: "unchanged",
|
|
17348
|
+
unavailable: "unavailable",
|
|
17349
|
+
"not-local": "not-local",
|
|
17350
|
+
"not-matching": "not-matching",
|
|
17351
|
+
failed: "failed"
|
|
17352
|
+
};
|
|
17353
|
+
var NotMatchingReasons = {
|
|
17354
|
+
"other-install": "other-install",
|
|
17355
|
+
"reload-unsupported": "reload-unsupported"
|
|
17356
|
+
};
|
|
17357
|
+
function notMatchingReason(err) {
|
|
17358
|
+
const status = err.details?.httpStatus;
|
|
17359
|
+
if (status === 401 || status === 403) return NotMatchingReasons["other-install"];
|
|
17360
|
+
if (err.details?.reason === ProviderReloadErrorReasons["install-identity-mismatch"]) return NotMatchingReasons["other-install"];
|
|
17361
|
+
if (isEndpointMissing(err) || status === 501) return NotMatchingReasons["reload-unsupported"];
|
|
17362
|
+
return void 0;
|
|
17363
|
+
}
|
|
17364
|
+
function notMatchingLines(reason, serverUrl) {
|
|
17365
|
+
switch (reason) {
|
|
17366
|
+
case NotMatchingReasons["other-install"]:
|
|
17367
|
+
return [
|
|
17368
|
+
`The server at ${serverUrl} is not this install's server, so it was not reloaded.`,
|
|
17369
|
+
"To apply the saved providers, run `canonry settings reload-providers` against this install's server, or restart that server."
|
|
17370
|
+
];
|
|
17371
|
+
case NotMatchingReasons["reload-unsupported"]:
|
|
17372
|
+
return [
|
|
17373
|
+
`The server at ${serverUrl} cannot reload providers: it is too old or does not support reload.`,
|
|
17374
|
+
"Restart this install's server to apply the saved providers."
|
|
17375
|
+
];
|
|
17376
|
+
}
|
|
17377
|
+
}
|
|
17304
17378
|
async function bootstrapCommand(opts) {
|
|
17305
17379
|
const format = opts?.format ?? "text";
|
|
17306
|
-
const env = getBootstrapEnv(process.env);
|
|
17307
|
-
const providers = env.providers;
|
|
17308
17380
|
const configDir = getConfigDir();
|
|
17309
17381
|
const existing = configExists();
|
|
17310
17382
|
const existingConfig = existing ? loadConfig() : void 0;
|
|
17311
17383
|
const existingRaw = existing ? loadConfigRaw() : null;
|
|
17384
|
+
const env = getBootstrapEnv(process.env);
|
|
17312
17385
|
const databasePath = env.databasePath || existingRaw?.database || path8.join(configDir, "data.db");
|
|
17313
17386
|
let rawApiKey;
|
|
17314
17387
|
let generatedApiKey;
|
|
@@ -17321,12 +17394,9 @@ async function bootstrapCommand(opts) {
|
|
|
17321
17394
|
rawApiKey = generatedApiKey;
|
|
17322
17395
|
}
|
|
17323
17396
|
const mergedProviders = { ...existingConfig?.providers };
|
|
17324
|
-
|
|
17325
|
-
|
|
17326
|
-
|
|
17327
|
-
if (providers.perplexity) mergedProviders.perplexity = providers.perplexity;
|
|
17328
|
-
if (providers.muse) mergedProviders.muse = providers.muse;
|
|
17329
|
-
if (providers.local) mergedProviders.local = providers.local;
|
|
17397
|
+
for (const [name, fromEnv] of Object.entries(env.providers)) {
|
|
17398
|
+
if (fromEnv) mergedProviders[name] = mergeEnvProvider(name, mergedProviders[name], fromEnv);
|
|
17399
|
+
}
|
|
17330
17400
|
if (env.googleClientId && !env.googleClientSecret || !env.googleClientId && env.googleClientSecret) {
|
|
17331
17401
|
console.warn("Warning: GOOGLE_CLIENT_ID and GOOGLE_CLIENT_SECRET must both be set to configure Google OAuth. Skipping Google auth config.");
|
|
17332
17402
|
}
|
|
@@ -17400,10 +17470,54 @@ async function bootstrapCommand(opts) {
|
|
|
17400
17470
|
providers: mergedProviders,
|
|
17401
17471
|
google: mergedGoogle
|
|
17402
17472
|
};
|
|
17403
|
-
const
|
|
17473
|
+
const providersChanged = !isDeepStrictEqual(persistedValue(existingRaw?.providers ?? {}), persistedValue(mergedProviders));
|
|
17474
|
+
const configChanged = !existingRaw || existingRaw.apiUrl !== apiUrl || existingRaw.database !== databasePath || existingRaw.apiKey !== rawApiKey || providersChanged || !isDeepStrictEqual(persistedValue(existingRaw.google), persistedValue(mergedGoogle));
|
|
17404
17475
|
if (configChanged) saveConfig(nextConfig);
|
|
17405
17476
|
const status = !existing ? "created" : configChanged || keyChanged ? "updated" : "unchanged";
|
|
17406
|
-
|
|
17477
|
+
const providerFree = registeredProviderNames(nextConfig).length === 0;
|
|
17478
|
+
const serverUrl = loadConfig().apiUrl;
|
|
17479
|
+
let serverReload;
|
|
17480
|
+
let reloadFailure;
|
|
17481
|
+
if (!isLoopbackBindHost(new URL(serverUrl).hostname)) {
|
|
17482
|
+
serverReload = { status: ServerReloadStatuses["not-local"] };
|
|
17483
|
+
} else if (!providersChanged) {
|
|
17484
|
+
serverReload = { status: ServerReloadStatuses.unchanged };
|
|
17485
|
+
} else {
|
|
17486
|
+
const signal = AbortSignal.timeout(4e3);
|
|
17487
|
+
try {
|
|
17488
|
+
const receipt = await createApiClient().reloadProviders({ configPath: getConfigPath(), databasePath }, signal);
|
|
17489
|
+
serverReload = {
|
|
17490
|
+
status: ServerReloadStatuses.reloaded,
|
|
17491
|
+
providers: receipt.providers.filter((provider) => provider.configured).map((provider) => provider.name)
|
|
17492
|
+
};
|
|
17493
|
+
} catch (err) {
|
|
17494
|
+
const reason = err instanceof CliError ? notMatchingReason(err) : void 0;
|
|
17495
|
+
if (err instanceof CliError && err.code === "CONNECTION_ERROR" && err.details?.connectionUnavailable === true && !signal.aborted) {
|
|
17496
|
+
serverReload = { status: ServerReloadStatuses.unavailable };
|
|
17497
|
+
} else if (err instanceof CliError && reason) {
|
|
17498
|
+
serverReload = { status: ServerReloadStatuses["not-matching"], reason, code: err.code };
|
|
17499
|
+
} else {
|
|
17500
|
+
reloadFailure = err instanceof CliError ? err : systemError("Provider configuration was saved, but server reload failed.");
|
|
17501
|
+
serverReload = { status: ServerReloadStatuses.failed, code: reloadFailure.code };
|
|
17502
|
+
}
|
|
17503
|
+
}
|
|
17504
|
+
}
|
|
17505
|
+
const reloadSteps = (() => {
|
|
17506
|
+
switch (serverReload.status) {
|
|
17507
|
+
case ServerReloadStatuses.unavailable:
|
|
17508
|
+
return ["Start `canonry serve` to use the saved configuration."];
|
|
17509
|
+
case ServerReloadStatuses.failed:
|
|
17510
|
+
return ["Resolve the server reload error, then run `canonry settings reload-providers`."];
|
|
17511
|
+
case ServerReloadStatuses["not-matching"]:
|
|
17512
|
+
return [notMatchingLines(serverReload.reason, serverUrl).join(" ")];
|
|
17513
|
+
case ServerReloadStatuses.reloaded:
|
|
17514
|
+
case ServerReloadStatuses.unchanged:
|
|
17515
|
+
case ServerReloadStatuses["not-local"]:
|
|
17516
|
+
return [];
|
|
17517
|
+
}
|
|
17518
|
+
})();
|
|
17519
|
+
const nextSteps = [...providerFree ? PROVIDER_FREE_NEXT_STEPS : [], ...reloadSteps];
|
|
17520
|
+
if (isMachineFormat(format)) {
|
|
17407
17521
|
console.log(JSON.stringify({
|
|
17408
17522
|
bootstrapped: true,
|
|
17409
17523
|
status,
|
|
@@ -17413,18 +17527,44 @@ async function bootstrapCommand(opts) {
|
|
|
17413
17527
|
apiUrl,
|
|
17414
17528
|
providers: Object.keys(mergedProviders),
|
|
17415
17529
|
googleConfigured: !!mergedGoogle,
|
|
17416
|
-
generatedApiKey
|
|
17530
|
+
generatedApiKey,
|
|
17531
|
+
serverReload,
|
|
17532
|
+
nextSteps
|
|
17417
17533
|
}, null, 2));
|
|
17534
|
+
if (reloadFailure) throw reloadFailure;
|
|
17418
17535
|
return;
|
|
17419
17536
|
}
|
|
17420
17537
|
console.log(`Bootstrap ${status}. Config: ${getConfigPath()}`);
|
|
17421
17538
|
console.log(`SQLite database path: ${databasePath}`);
|
|
17422
|
-
|
|
17539
|
+
switch (serverReload.status) {
|
|
17540
|
+
case ServerReloadStatuses.reloaded:
|
|
17541
|
+
console.log(`Providers active on the running server: ${serverReload.providers.join(", ") || "none"}.`);
|
|
17542
|
+
break;
|
|
17543
|
+
case ServerReloadStatuses.unavailable:
|
|
17544
|
+
console.log("Start `canonry serve` to use the saved configuration.");
|
|
17545
|
+
break;
|
|
17546
|
+
case ServerReloadStatuses["not-local"]:
|
|
17547
|
+
console.log("Configuration saved locally. The configured remote server was not reloaded.");
|
|
17548
|
+
break;
|
|
17549
|
+
case ServerReloadStatuses["not-matching"]:
|
|
17550
|
+
for (const line of notMatchingLines(serverReload.reason, serverUrl)) console.log(line);
|
|
17551
|
+
break;
|
|
17552
|
+
case ServerReloadStatuses.unchanged:
|
|
17553
|
+
if (existing) console.log("Provider settings unchanged, so the server was not reloaded.");
|
|
17554
|
+
break;
|
|
17555
|
+
case ServerReloadStatuses.failed:
|
|
17556
|
+
break;
|
|
17557
|
+
}
|
|
17558
|
+
if (providerFree) {
|
|
17423
17559
|
console.log("Providers: none (Page Health works now; add one later to enable AI Visibility).");
|
|
17560
|
+
console.log(" To add one with the server running: canonry settings provider gemini --api-key <key>");
|
|
17561
|
+
console.log(" (free key at aistudio.google.com). Or set GEMINI_API_KEY and rerun `canonry bootstrap`;");
|
|
17562
|
+
console.log(" bootstrap reloads the matching running local server and confirms active providers.");
|
|
17424
17563
|
}
|
|
17425
17564
|
if (generatedApiKey) {
|
|
17426
17565
|
console.log(`API key (for the CLI, MCP, and agents): ${generatedApiKey}`);
|
|
17427
17566
|
}
|
|
17567
|
+
if (reloadFailure) throw reloadFailure;
|
|
17428
17568
|
}
|
|
17429
17569
|
|
|
17430
17570
|
// src/commands/daemon.ts
|
|
@@ -17756,7 +17896,9 @@ async function initCommand(opts) {
|
|
|
17756
17896
|
});
|
|
17757
17897
|
}
|
|
17758
17898
|
if (nonInteractive) {
|
|
17759
|
-
Object.
|
|
17899
|
+
for (const [name, entry] of Object.entries(envProviders)) {
|
|
17900
|
+
if (entry) providers[name] = withBootstrapProviderDefaults(name, entry);
|
|
17901
|
+
}
|
|
17760
17902
|
if (envGoogleConfigured) {
|
|
17761
17903
|
google = {
|
|
17762
17904
|
clientId: bootstrapEnv.googleClientId,
|
|
@@ -18384,9 +18526,7 @@ Canonry server running at ${url}`);
|
|
|
18384
18526
|
}, null, 2));
|
|
18385
18527
|
}
|
|
18386
18528
|
setTelemetrySource("cli-server");
|
|
18387
|
-
const providerNames =
|
|
18388
|
-
(k) => config.providers?.[k]?.apiKey || config.providers?.[k]?.baseUrl
|
|
18389
|
-
);
|
|
18529
|
+
const providerNames = registeredProviderNames(config);
|
|
18390
18530
|
trackEvent("serve.started", {
|
|
18391
18531
|
providerCount: providerNames.length,
|
|
18392
18532
|
providers: providerNames,
|
|
@@ -22070,14 +22210,48 @@ var NUDGE_EXEMPT_ROOTS = /* @__PURE__ */ new Set([
|
|
|
22070
22210
|
"status",
|
|
22071
22211
|
"unknown"
|
|
22072
22212
|
]);
|
|
22213
|
+
var PAGE_HEALTH_HANDOFF_COMMANDS = /* @__PURE__ */ new Set([
|
|
22214
|
+
"technical-aeo.run",
|
|
22215
|
+
"technical-aeo.score",
|
|
22216
|
+
"technical-aeo.crawl",
|
|
22217
|
+
"site-health.overview"
|
|
22218
|
+
]);
|
|
22219
|
+
var NO_PROVIDER_NOTICE_CODE = "NO_PROVIDER";
|
|
22220
|
+
var PROVIDER_SETUP_COMMAND = "canonry settings provider gemini --api-key <key>";
|
|
22221
|
+
var GEMINI_KEY_URL = "https://aistudio.google.com/apikey";
|
|
22073
22222
|
function buildSetupNudgeLine(input) {
|
|
22074
|
-
|
|
22075
|
-
const
|
|
22076
|
-
if (
|
|
22223
|
+
const machineFormat = isMachineFormat(input.format);
|
|
22224
|
+
const handoff = PAGE_HEALTH_HANDOFF_COMMANDS.has(input.command);
|
|
22225
|
+
if (!handoff) {
|
|
22226
|
+
if (machineFormat || !input.stderrIsTTY) return null;
|
|
22227
|
+
const [root = input.command] = input.command.split(".");
|
|
22228
|
+
if (NUDGE_EXEMPT_ROOTS.has(root)) return null;
|
|
22229
|
+
}
|
|
22077
22230
|
const setupState = input.getSetupState();
|
|
22078
22231
|
if (!setupState) return null;
|
|
22079
22232
|
if (setupState.provider_count > 0) return null;
|
|
22080
|
-
|
|
22233
|
+
if (setupState.project_count === 0) return null;
|
|
22234
|
+
if (machineFormat) {
|
|
22235
|
+
return `${JSON.stringify({
|
|
22236
|
+
notice: {
|
|
22237
|
+
code: NO_PROVIDER_NOTICE_CODE,
|
|
22238
|
+
message: "AI Visibility needs an answer-engine provider. Page Health does not.",
|
|
22239
|
+
setupCommand: PROVIDER_SETUP_COMMAND,
|
|
22240
|
+
keyUrl: GEMINI_KEY_URL,
|
|
22241
|
+
note: "A provider key is the operator's credential: they add it in the dashboard, or run the setup command in their own terminal while the server is running. Never ask for it in chat."
|
|
22242
|
+
}
|
|
22243
|
+
})}
|
|
22244
|
+
`;
|
|
22245
|
+
}
|
|
22246
|
+
if (!input.stderrIsTTY) {
|
|
22247
|
+
return `[canonry] ${NO_PROVIDER_NOTICE_CODE}: AI Visibility needs an answer-engine provider. Page Health does not. The operator adds a key in the dashboard, or runs \`${PROVIDER_SETUP_COMMAND}\` in their own terminal while the server is running (free key at ${GEMINI_KEY_URL}). Never ask for the key in chat.
|
|
22248
|
+
`;
|
|
22249
|
+
}
|
|
22250
|
+
return `
|
|
22251
|
+
\u2192 AI Visibility needs an answer-engine provider. Page Health does not.
|
|
22252
|
+
Add one in the dashboard after \`canonry serve\`, or while the server is running:
|
|
22253
|
+
${PROVIDER_SETUP_COMMAND} (free key at aistudio.google.com)
|
|
22254
|
+
`;
|
|
22081
22255
|
}
|
|
22082
22256
|
|
|
22083
22257
|
// src/cli.ts
|
|
@@ -22257,7 +22431,7 @@ async function runCli(args = process.argv.slice(2)) {
|
|
|
22257
22431
|
}
|
|
22258
22432
|
const nudge = buildSetupNudgeLine({
|
|
22259
22433
|
command: resolvedCommand,
|
|
22260
|
-
|
|
22434
|
+
format,
|
|
22261
22435
|
stderrIsTTY: Boolean(process.stderr.isTTY),
|
|
22262
22436
|
getSetupState: buildSetupState
|
|
22263
22437
|
});
|
|
@@ -5,11 +5,11 @@ import {
|
|
|
5
5
|
computeFactorAverages,
|
|
6
6
|
layoutSiteCrawlGraphInput,
|
|
7
7
|
persistSiteCrawlGraphLayout
|
|
8
|
-
} from "./chunk-
|
|
8
|
+
} from "./chunk-222NAFTY.js";
|
|
9
9
|
import {
|
|
10
10
|
PACKAGE_VERSION,
|
|
11
11
|
canonryMcpTools
|
|
12
|
-
} from "./chunk-
|
|
12
|
+
} from "./chunk-5IXQAOVK.js";
|
|
13
13
|
import {
|
|
14
14
|
HISTORY_WINDOW_RUNS,
|
|
15
15
|
IntelligenceService,
|
|
@@ -85,7 +85,7 @@ import {
|
|
|
85
85
|
siteCrawlPages,
|
|
86
86
|
siteCrawlSnapshots,
|
|
87
87
|
trafficSources
|
|
88
|
-
} from "./chunk-
|
|
88
|
+
} from "./chunk-46JZR2IV.js";
|
|
89
89
|
import {
|
|
90
90
|
RunKinds,
|
|
91
91
|
SiteCrawlFetchStates,
|
|
@@ -115,7 +115,7 @@ import {
|
|
|
115
115
|
roundPreservingTotal,
|
|
116
116
|
siteAuditPageFactorSchema,
|
|
117
117
|
wilsonInterval
|
|
118
|
-
} from "./chunk-
|
|
118
|
+
} from "./chunk-MRKV43TV.js";
|
|
119
119
|
|
|
120
120
|
// src/demo-server.ts
|
|
121
121
|
import { dirname, join as join2 } from "path";
|
package/dist/index.d.ts
CHANGED
|
@@ -453,7 +453,7 @@ interface CanonryConfig {
|
|
|
453
453
|
places?: PlacesConfigEntry;
|
|
454
454
|
embed?: EmbedConfigEntry;
|
|
455
455
|
}
|
|
456
|
-
declare function loadConfig(): CanonryConfig;
|
|
456
|
+
declare function loadConfig(configPath?: string): CanonryConfig;
|
|
457
457
|
|
|
458
458
|
declare function createServer(opts: {
|
|
459
459
|
config: CanonryConfig;
|
package/dist/index.js
CHANGED
|
@@ -3,14 +3,14 @@ import {
|
|
|
3
3
|
createGoogleMarketingCredentialStore,
|
|
4
4
|
createGoogleMarketingRuntime,
|
|
5
5
|
createServer
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-CIPWGVX6.js";
|
|
7
7
|
import {
|
|
8
8
|
loadConfig
|
|
9
|
-
} from "./chunk-
|
|
10
|
-
import "./chunk-
|
|
11
|
-
import "./chunk-
|
|
12
|
-
import "./chunk-
|
|
13
|
-
import "./chunk-
|
|
9
|
+
} from "./chunk-NDQOCFJQ.js";
|
|
10
|
+
import "./chunk-222NAFTY.js";
|
|
11
|
+
import "./chunk-5IXQAOVK.js";
|
|
12
|
+
import "./chunk-46JZR2IV.js";
|
|
13
|
+
import "./chunk-MRKV43TV.js";
|
|
14
14
|
export {
|
|
15
15
|
GoogleMarketingRuntimeError,
|
|
16
16
|
createGoogleMarketingCredentialStore,
|
package/dist/mcp.js
CHANGED
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
import {
|
|
2
2
|
autoSyncSkills
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-6H2BC5EY.js";
|
|
4
4
|
import {
|
|
5
5
|
createApiClient,
|
|
6
6
|
createCanonryMcpServer
|
|
7
|
-
} from "./chunk-
|
|
8
|
-
import "./chunk-
|
|
7
|
+
} from "./chunk-NDQOCFJQ.js";
|
|
8
|
+
import "./chunk-5IXQAOVK.js";
|
|
9
9
|
import {
|
|
10
10
|
isReadOnlyKey,
|
|
11
11
|
updateCheckEnvOptOut
|
|
12
|
-
} from "./chunk-
|
|
12
|
+
} from "./chunk-MRKV43TV.js";
|
|
13
13
|
|
|
14
14
|
// src/mcp/cli.ts
|
|
15
15
|
import { randomUUID } from "crypto";
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@canonry/canonry",
|
|
3
|
-
"version": "7.
|
|
3
|
+
"version": "7.20.1",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Self-hosted AI visibility (AEO) platform: track how ChatGPT, Claude, Gemini, and Perplexity cite your domain, join it with Search Console, GA4, server-side traffic, and paid media, and fix what you find through agent tools (CLI, REST, MCP). Local SQLite.",
|
|
6
6
|
"keywords": [
|
|
@@ -89,30 +89,30 @@
|
|
|
89
89
|
"@ainyc/canonry-api-client": "0.0.0",
|
|
90
90
|
"@ainyc/canonry-api-routes": "0.0.0",
|
|
91
91
|
"@ainyc/canonry-contracts": "0.0.0",
|
|
92
|
-
"@ainyc/canonry-config": "0.0.0",
|
|
93
92
|
"@ainyc/canonry-db": "0.0.0",
|
|
94
|
-
"@ainyc/canonry-
|
|
93
|
+
"@ainyc/canonry-config": "0.0.0",
|
|
95
94
|
"@ainyc/canonry-integration-cloud-run": "0.0.0",
|
|
96
|
-
"@ainyc/canonry-integration-
|
|
95
|
+
"@ainyc/canonry-integration-bing": "0.0.0",
|
|
97
96
|
"@ainyc/canonry-integration-cloudflare-queue": "0.0.0",
|
|
97
|
+
"@ainyc/canonry-integration-cloudflare-worker": "0.0.0",
|
|
98
|
+
"@ainyc/canonry-integration-commoncrawl": "0.0.0",
|
|
98
99
|
"@ainyc/canonry-integration-google-business-profile": "0.0.0",
|
|
99
100
|
"@ainyc/canonry-integration-google-ads": "0.0.0",
|
|
100
|
-
"@ainyc/canonry-integration-google": "0.0.0",
|
|
101
101
|
"@ainyc/canonry-integration-google-places": "0.0.0",
|
|
102
|
-
"@ainyc/canonry-integration-openai-ads": "0.0.0",
|
|
103
102
|
"@ainyc/canonry-integration-google-tag-manager": "0.0.0",
|
|
104
103
|
"@ainyc/canonry-integration-traffic": "0.0.0",
|
|
104
|
+
"@ainyc/canonry-integration-openai-ads": "0.0.0",
|
|
105
105
|
"@ainyc/canonry-integration-wordpress": "0.0.0",
|
|
106
|
-
"@ainyc/canonry-integration-
|
|
106
|
+
"@ainyc/canonry-integration-google": "0.0.0",
|
|
107
|
+
"@ainyc/canonry-provider-claude": "0.0.0",
|
|
107
108
|
"@ainyc/canonry-intelligence": "0.0.0",
|
|
108
109
|
"@ainyc/canonry-provider-cdp": "0.0.0",
|
|
109
|
-
"@ainyc/canonry-provider-claude": "0.0.0",
|
|
110
110
|
"@ainyc/canonry-provider-gemini": "0.0.0",
|
|
111
|
-
"@ainyc/canonry-provider-
|
|
112
|
-
"@ainyc/canonry-provider-perplexity": "0.0.0",
|
|
111
|
+
"@ainyc/canonry-provider-local": "0.0.0",
|
|
113
112
|
"@ainyc/canonry-provider-openai": "0.0.0",
|
|
114
|
-
"@ainyc/canonry-
|
|
115
|
-
"@ainyc/canonry-provider-
|
|
113
|
+
"@ainyc/canonry-provider-perplexity": "0.0.0",
|
|
114
|
+
"@ainyc/canonry-provider-muse": "0.0.0",
|
|
115
|
+
"@ainyc/canonry-integration-typesafe": "0.0.0"
|
|
116
116
|
},
|
|
117
117
|
"scripts": {
|
|
118
118
|
"build": "pnpm run build:cli && pnpm run build:web",
|