@ainyc/canonry 4.76.2 → 4.78.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/assets/assets/{BacklinksPage-GkTp8zLM.js → BacklinksPage-CwXveumn.js} +1 -1
- package/assets/assets/{ChartPrimitives-0noLg9_T.js → ChartPrimitives-DntKGI5J.js} +1 -1
- package/assets/assets/{ProjectPage-Bg5sKYhO.js → ProjectPage-CVudiU8X.js} +4 -4
- package/assets/assets/{RunRow-BEhaQDol.js → RunRow-DMtYXaxG.js} +1 -1
- package/assets/assets/{RunsPage-CV2wKkaz.js → RunsPage-Cz-YlucO.js} +1 -1
- package/assets/assets/{SettingsPage-Ctij-T9F.js → SettingsPage-BCuG3C-0.js} +1 -1
- package/assets/assets/TrafficPage-DV8X47wa.js +1 -0
- package/assets/assets/TrafficSourceDetailPage-BmYhK9jm.js +1 -0
- package/assets/assets/arrow-left-CUmHyNnF.js +1 -0
- package/assets/assets/extract-error-message-DFjy9_zi.js +1 -0
- package/assets/assets/{index-DRhoqa2-.css → index-BgWgJE7S.css} +1 -1
- package/assets/assets/{index-B-_Dwwhd.js → index-D9smxU6R.js} +4 -4
- package/assets/assets/{trash-2-C65kNIO5.js → trash-2-B_UtEEm8.js} +1 -1
- package/assets/index.html +2 -2
- package/dist/{chunk-BIT3JPMW.js → chunk-3WXARKUE.js} +105 -15
- package/dist/{chunk-ETM5EPQH.js → chunk-KPN22EWK.js} +2 -2
- package/dist/{chunk-ZUQK4TLL.js → chunk-QKTIP6GC.js} +46 -17
- package/dist/{chunk-42TDEKKM.js → chunk-XI6YSTGE.js} +1 -1
- package/dist/cli.js +13 -4
- package/dist/index.js +4 -4
- package/dist/{intelligence-service-QIGX7IVQ.js → intelligence-service-CDVUUG7O.js} +2 -2
- package/dist/mcp.js +2 -2
- package/package.json +10 -10
- package/assets/assets/TrafficPage-TnIPaMcL.js +0 -1
- package/assets/assets/TrafficSourceDetailPage-BBmIwaee.js +0 -1
- package/assets/assets/extract-error-message-BdLppivS.js +0 -1
- package/assets/assets/server-traffic-ScU00kCP.js +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
import{c}from"./index-
|
|
1
|
+
import{c}from"./index-D9smxU6R.js";const a=[["circle",{cx:"12",cy:"12",r:"10",key:"1mglay"}],["path",{d:"m9 12 2 2 4-4",key:"dzmm74"}]],h=c("circle-check",a);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"}]],n=c("circle-question-mark",e);const o=[["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=c("download",o);const t=[["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"}]],r=c("trash-2",t);export{h as C,s as D,r as T,n 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-D9smxU6R.js"></script>
|
|
16
16
|
<link rel="modulepreload" crossorigin href="./assets/vendor-tanstack-Dq7p98wZ.js">
|
|
17
17
|
<link rel="modulepreload" crossorigin href="./assets/vendor-radix-B57xfQbP.js">
|
|
18
18
|
<link rel="modulepreload" crossorigin href="./assets/vendor-recharts-ClRVR6aX.js">
|
|
19
19
|
<link rel="modulepreload" crossorigin href="./assets/vendor-markdown-DK7fbRNb.js">
|
|
20
|
-
<link rel="stylesheet" crossorigin href="./assets/index-
|
|
20
|
+
<link rel="stylesheet" crossorigin href="./assets/index-BgWgJE7S.css">
|
|
21
21
|
</head>
|
|
22
22
|
<body>
|
|
23
23
|
<div id="root"></div>
|
|
@@ -232,7 +232,7 @@ import {
|
|
|
232
232
|
wordpressSchemaDeployResultDtoSchema,
|
|
233
233
|
wordpressSchemaStatusResultDtoSchema,
|
|
234
234
|
wordpressStatusDtoSchema
|
|
235
|
-
} from "./chunk-
|
|
235
|
+
} from "./chunk-KPN22EWK.js";
|
|
236
236
|
|
|
237
237
|
// src/intelligence-service.ts
|
|
238
238
|
import { eq as eq33, desc as desc17, asc as asc4, and as and24, ne as ne5, or as or5, inArray as inArray12, gte as gte6, lte as lte3 } from "drizzle-orm";
|
|
@@ -19153,6 +19153,68 @@ async function getValidToken(store, domain, connectionType, clientId, clientSecr
|
|
|
19153
19153
|
propertyId: conn.propertyId ?? null
|
|
19154
19154
|
};
|
|
19155
19155
|
}
|
|
19156
|
+
function parseGscApiDisabled(message) {
|
|
19157
|
+
if (!/accessNotConfigured|SERVICE_DISABLED|has not been used in project|is disabled/i.test(message)) {
|
|
19158
|
+
return null;
|
|
19159
|
+
}
|
|
19160
|
+
const projectNumber = message.match(/[?&]project=(\d+)/)?.[1] ?? message.match(/project\s+(\d+)/i)?.[1] ?? null;
|
|
19161
|
+
const base = "https://console.developers.google.com/apis/api";
|
|
19162
|
+
const qs = projectNumber ? `?project=${projectNumber}` : "";
|
|
19163
|
+
return {
|
|
19164
|
+
projectNumber,
|
|
19165
|
+
enableUrl: `${base}/searchconsole.googleapis.com/overview${qs}`,
|
|
19166
|
+
indexingApiUrl: `${base}/indexing.googleapis.com/overview${qs}`
|
|
19167
|
+
};
|
|
19168
|
+
}
|
|
19169
|
+
function googleAuthErrorStatus(err) {
|
|
19170
|
+
if (err.statusCode != null) return err.statusCode;
|
|
19171
|
+
const match = err.message.match(/failed \((\d{3})\)/);
|
|
19172
|
+
return match ? Number(match[1]) : null;
|
|
19173
|
+
}
|
|
19174
|
+
function gscErrorToAppError(err, context) {
|
|
19175
|
+
if (err instanceof AppError) return err;
|
|
19176
|
+
if (err instanceof GoogleApiError) {
|
|
19177
|
+
if (err.status === 429) {
|
|
19178
|
+
return quotaExceeded("Google Search Console API (rate limited; retries exhausted)");
|
|
19179
|
+
}
|
|
19180
|
+
if (err.status === 403) {
|
|
19181
|
+
const disabled = parseGscApiDisabled(err.message);
|
|
19182
|
+
if (disabled) {
|
|
19183
|
+
const inProject = disabled.projectNumber ? ` (project ${disabled.projectNumber})` : "";
|
|
19184
|
+
return forbidden(
|
|
19185
|
+
`${context}: the Google Search Console API is not enabled for your Google Cloud project${inProject}. Enable the Search Console API and the Indexing API, wait ~2\u20135 minutes, then retry: ${disabled.enableUrl}`,
|
|
19186
|
+
{ reason: "gsc-api-disabled", upstreamStatus: 403, ...disabled }
|
|
19187
|
+
);
|
|
19188
|
+
}
|
|
19189
|
+
return forbidden(
|
|
19190
|
+
`${context}: the connected Google account does not have access to a verified Search Console property for this domain. Connect the account that owns the property.`,
|
|
19191
|
+
{ reason: "gsc-no-property-access", upstreamStatus: 403 }
|
|
19192
|
+
);
|
|
19193
|
+
}
|
|
19194
|
+
if (err.status === 401) {
|
|
19195
|
+
return forbidden(
|
|
19196
|
+
`${context}: the Google connection has expired or was revoked. Reconnect Google Search Console.`,
|
|
19197
|
+
{ reason: "gsc-reconnect", upstreamStatus: 401 }
|
|
19198
|
+
);
|
|
19199
|
+
}
|
|
19200
|
+
return providerError(`${context}: ${err.message}`, { upstreamStatus: err.status });
|
|
19201
|
+
}
|
|
19202
|
+
if (err instanceof GoogleAuthError) {
|
|
19203
|
+
const status = googleAuthErrorStatus(err);
|
|
19204
|
+
if (status === 429) return quotaExceeded("Google OAuth token refresh (rate limited)");
|
|
19205
|
+
if (status != null && status >= 400 && status < 500) {
|
|
19206
|
+
return forbidden(
|
|
19207
|
+
`${context}: the stored Google credentials are no longer valid (token refresh failed). Reconnect Google Search Console.`,
|
|
19208
|
+
{ reason: "gsc-reconnect", upstreamStatus: status }
|
|
19209
|
+
);
|
|
19210
|
+
}
|
|
19211
|
+
return providerError(
|
|
19212
|
+
`${context}: ${err.message}. Reconnect Google Search Console if this persists.`,
|
|
19213
|
+
status != null ? { upstreamStatus: status } : void 0
|
|
19214
|
+
);
|
|
19215
|
+
}
|
|
19216
|
+
return providerError(`${context}: ${err instanceof Error ? err.message : String(err)}`);
|
|
19217
|
+
}
|
|
19156
19218
|
async function googleRoutes(app, opts) {
|
|
19157
19219
|
if (opts.googleStateSecret === void 0) {
|
|
19158
19220
|
app.log.warn(
|
|
@@ -19375,9 +19437,13 @@ async function googleRoutes(app, opts) {
|
|
|
19375
19437
|
}
|
|
19376
19438
|
const store = requireConnectionStore();
|
|
19377
19439
|
const project = resolveProject(app.db, request.params.name);
|
|
19378
|
-
|
|
19379
|
-
|
|
19380
|
-
|
|
19440
|
+
try {
|
|
19441
|
+
const { accessToken } = await getValidToken(store, project.canonicalDomain, "gsc", googleClientId, googleClientSecret);
|
|
19442
|
+
const sites = await listSites(accessToken);
|
|
19443
|
+
return { sites };
|
|
19444
|
+
} catch (err) {
|
|
19445
|
+
throw gscErrorToAppError(err, "Failed to list Search Console properties");
|
|
19446
|
+
}
|
|
19381
19447
|
});
|
|
19382
19448
|
app.post("/projects/:name/google/gsc/sync", async (request) => {
|
|
19383
19449
|
const store = requireConnectionStore();
|
|
@@ -19470,11 +19536,16 @@ async function googleRoutes(app, opts) {
|
|
|
19470
19536
|
if (!url) {
|
|
19471
19537
|
throw validationError("url is required");
|
|
19472
19538
|
}
|
|
19473
|
-
|
|
19474
|
-
|
|
19475
|
-
|
|
19539
|
+
let result;
|
|
19540
|
+
try {
|
|
19541
|
+
const { accessToken, propertyId } = await getValidToken(store, project.canonicalDomain, "gsc", googleClientId, googleClientSecret);
|
|
19542
|
+
if (!propertyId) {
|
|
19543
|
+
throw validationError("No GSC property configured for this connection");
|
|
19544
|
+
}
|
|
19545
|
+
result = await inspectUrl(accessToken, url, propertyId);
|
|
19546
|
+
} catch (err) {
|
|
19547
|
+
throw gscErrorToAppError(err, "Failed to inspect URL in Search Console");
|
|
19476
19548
|
}
|
|
19477
|
-
const result = await inspectUrl(accessToken, url, propertyId);
|
|
19478
19549
|
const ir = result.inspectionResult;
|
|
19479
19550
|
const idx = ir.indexStatusResult;
|
|
19480
19551
|
const mob = ir.mobileUsabilityResult;
|
|
@@ -19682,12 +19753,16 @@ async function googleRoutes(app, opts) {
|
|
|
19682
19753
|
}
|
|
19683
19754
|
const store = requireConnectionStore();
|
|
19684
19755
|
const project = resolveProject(app.db, request.params.name);
|
|
19685
|
-
|
|
19686
|
-
|
|
19687
|
-
|
|
19756
|
+
try {
|
|
19757
|
+
const { accessToken, propertyId } = await getValidToken(store, project.canonicalDomain, "gsc", googleClientId, googleClientSecret);
|
|
19758
|
+
if (!propertyId) {
|
|
19759
|
+
throw validationError('No GSC property configured for this connection. Set one with "canonry google set-property".');
|
|
19760
|
+
}
|
|
19761
|
+
const sitemaps = await listSitemaps(accessToken, propertyId);
|
|
19762
|
+
return { sitemaps };
|
|
19763
|
+
} catch (err) {
|
|
19764
|
+
throw gscErrorToAppError(err, "Failed to list Search Console sitemaps");
|
|
19688
19765
|
}
|
|
19689
|
-
const sitemaps = await listSitemaps(accessToken, propertyId);
|
|
19690
|
-
return { sitemaps };
|
|
19691
19766
|
});
|
|
19692
19767
|
app.post("/projects/:name/google/gsc/discover-sitemaps", async (request) => {
|
|
19693
19768
|
const { clientId: googleClientId, clientSecret: googleClientSecret } = getAuthConfig();
|
|
@@ -19703,8 +19778,13 @@ async function googleRoutes(app, opts) {
|
|
|
19703
19778
|
if (!conn.propertyId) {
|
|
19704
19779
|
throw validationError("No GSC property configured for this connection");
|
|
19705
19780
|
}
|
|
19706
|
-
|
|
19707
|
-
|
|
19781
|
+
let sitemaps;
|
|
19782
|
+
try {
|
|
19783
|
+
const { accessToken } = await getValidToken(store, project.canonicalDomain, "gsc", googleClientId, googleClientSecret);
|
|
19784
|
+
sitemaps = await listSitemaps(accessToken, conn.propertyId);
|
|
19785
|
+
} catch (err) {
|
|
19786
|
+
throw gscErrorToAppError(err, "Failed to discover Search Console sitemaps");
|
|
19787
|
+
}
|
|
19708
19788
|
if (sitemaps.length === 0) {
|
|
19709
19789
|
throw validationError("No sitemaps found for this GSC property. Submit a sitemap in Google Search Console first.");
|
|
19710
19790
|
}
|
|
@@ -24303,6 +24383,8 @@ var CloudRunAuthError = class extends Error {
|
|
|
24303
24383
|
this.body = body;
|
|
24304
24384
|
this.name = "CloudRunAuthError";
|
|
24305
24385
|
}
|
|
24386
|
+
httpStatus;
|
|
24387
|
+
body;
|
|
24306
24388
|
};
|
|
24307
24389
|
function createServiceAccountJwt2(clientEmail, privateKey, scope) {
|
|
24308
24390
|
if (!clientEmail) throw new CloudRunAuthError("clientEmail is required");
|
|
@@ -24479,6 +24561,8 @@ var CloudRunLoggingApiError = class extends Error {
|
|
|
24479
24561
|
this.body = body;
|
|
24480
24562
|
this.name = "CloudRunLoggingApiError";
|
|
24481
24563
|
}
|
|
24564
|
+
status;
|
|
24565
|
+
body;
|
|
24482
24566
|
};
|
|
24483
24567
|
function validateAccessToken3(accessToken) {
|
|
24484
24568
|
if (!accessToken.trim()) {
|
|
@@ -27533,6 +27617,8 @@ var WordpressTrafficApiError = class extends Error {
|
|
|
27533
27617
|
this.body = body;
|
|
27534
27618
|
this.name = "WordpressTrafficApiError";
|
|
27535
27619
|
}
|
|
27620
|
+
status;
|
|
27621
|
+
body;
|
|
27536
27622
|
};
|
|
27537
27623
|
function trimRequired(name, value) {
|
|
27538
27624
|
const trimmed = value.trim();
|
|
@@ -27734,6 +27820,9 @@ var VercelLogsApiError = class extends Error {
|
|
|
27734
27820
|
this.retryAfterSeconds = retryAfterSeconds;
|
|
27735
27821
|
this.name = "VercelLogsApiError";
|
|
27736
27822
|
}
|
|
27823
|
+
status;
|
|
27824
|
+
body;
|
|
27825
|
+
retryAfterSeconds;
|
|
27737
27826
|
};
|
|
27738
27827
|
function parseRetryAfter2(headerValue) {
|
|
27739
27828
|
if (!headerValue) return void 0;
|
|
@@ -32571,6 +32660,7 @@ var IntelligenceService = class {
|
|
|
32571
32660
|
constructor(db) {
|
|
32572
32661
|
this.db = db;
|
|
32573
32662
|
}
|
|
32663
|
+
db;
|
|
32574
32664
|
/**
|
|
32575
32665
|
* Analyze a completed run and persist insights + health snapshot.
|
|
32576
32666
|
* Idempotent: deletes prior results for the same runId before inserting.
|
|
@@ -41,8 +41,8 @@ function authRequired(message = "Authentication required") {
|
|
|
41
41
|
function authInvalid() {
|
|
42
42
|
return new AppError("AUTH_INVALID", "Invalid API key", 401);
|
|
43
43
|
}
|
|
44
|
-
function forbidden(message = "Forbidden") {
|
|
45
|
-
return new AppError("FORBIDDEN", message, 403);
|
|
44
|
+
function forbidden(message = "Forbidden", details) {
|
|
45
|
+
return new AppError("FORBIDDEN", message, 403, details);
|
|
46
46
|
}
|
|
47
47
|
function quotaExceeded(metric) {
|
|
48
48
|
return new AppError("QUOTA_EXCEEDED", `Quota exceeded for ${metric}`, 429);
|
|
@@ -9,7 +9,7 @@ import {
|
|
|
9
9
|
loadConfig,
|
|
10
10
|
loadConfigRaw,
|
|
11
11
|
saveConfigPatch
|
|
12
|
-
} from "./chunk-
|
|
12
|
+
} from "./chunk-XI6YSTGE.js";
|
|
13
13
|
import {
|
|
14
14
|
CC_CACHE_DIR,
|
|
15
15
|
DUCKDB_SPEC,
|
|
@@ -97,7 +97,7 @@ import {
|
|
|
97
97
|
siteAuditPages,
|
|
98
98
|
siteAuditSnapshots,
|
|
99
99
|
usageCounters
|
|
100
|
-
} from "./chunk-
|
|
100
|
+
} from "./chunk-3WXARKUE.js";
|
|
101
101
|
import {
|
|
102
102
|
AGENT_MEMORY_VALUE_MAX_BYTES,
|
|
103
103
|
AGENT_PROVIDER_IDS,
|
|
@@ -149,7 +149,7 @@ import {
|
|
|
149
149
|
validationError,
|
|
150
150
|
winnabilityClassLabel,
|
|
151
151
|
withRetry
|
|
152
|
-
} from "./chunk-
|
|
152
|
+
} from "./chunk-KPN22EWK.js";
|
|
153
153
|
|
|
154
154
|
// src/telemetry.ts
|
|
155
155
|
import crypto from "crypto";
|
|
@@ -476,15 +476,17 @@ function resolveModel(config) {
|
|
|
476
476
|
return config.model || DEFAULT_MODEL;
|
|
477
477
|
}
|
|
478
478
|
function createClient2(config) {
|
|
479
|
+
const httpOptions = config.baseUrl ? { httpOptions: { baseUrl: config.baseUrl } } : {};
|
|
479
480
|
if (isVertexConfig(config)) {
|
|
480
481
|
return new GoogleGenAI({
|
|
481
482
|
vertexai: true,
|
|
482
483
|
project: config.vertexProject,
|
|
483
484
|
location: config.vertexRegion || "us-central1",
|
|
484
|
-
...config.vertexCredentials ? { googleAuthOptions: { keyFilename: config.vertexCredentials } } : {}
|
|
485
|
+
...config.vertexCredentials ? { googleAuthOptions: { keyFilename: config.vertexCredentials } } : {},
|
|
486
|
+
...httpOptions
|
|
485
487
|
});
|
|
486
488
|
}
|
|
487
|
-
return new GoogleGenAI({ apiKey: config.apiKey });
|
|
489
|
+
return new GoogleGenAI({ apiKey: config.apiKey, ...httpOptions });
|
|
488
490
|
}
|
|
489
491
|
function validateConfig(config) {
|
|
490
492
|
if ("vertexProject" in config && config.vertexProject !== void 0 && config.vertexProject.trim().length === 0) {
|
|
@@ -749,7 +751,7 @@ async function embedQueries(queries2, options) {
|
|
|
749
751
|
if (!options.apiKey && !options.client) {
|
|
750
752
|
throw new Error("embedQueries: missing apiKey");
|
|
751
753
|
}
|
|
752
|
-
const client = options.client ?? createGeminiEmbedClient(options.apiKey);
|
|
754
|
+
const client = options.client ?? createGeminiEmbedClient(options.apiKey, options.baseUrl);
|
|
753
755
|
return client.embedBatch(queries2, {
|
|
754
756
|
model: options.model ?? DEFAULT_EMBED_MODEL,
|
|
755
757
|
taskType: CLUSTERING_TASK_TYPE,
|
|
@@ -770,8 +772,11 @@ function extractEmbeddingVectors(response, expectedLength) {
|
|
|
770
772
|
return e.values;
|
|
771
773
|
});
|
|
772
774
|
}
|
|
773
|
-
function
|
|
774
|
-
|
|
775
|
+
function createEmbedGenAI(apiKey, baseUrl) {
|
|
776
|
+
return new GoogleGenAI2({ apiKey, ...baseUrl ? { httpOptions: { baseUrl } } : {} });
|
|
777
|
+
}
|
|
778
|
+
function createGeminiEmbedClient(apiKey, baseUrl) {
|
|
779
|
+
const genai = createEmbedGenAI(apiKey, baseUrl);
|
|
775
780
|
return {
|
|
776
781
|
async embedBatch(queries2, opts) {
|
|
777
782
|
const response = await genai.models.embedContent({
|
|
@@ -792,6 +797,7 @@ function toGeminiConfig(config) {
|
|
|
792
797
|
return {
|
|
793
798
|
apiKey: config.apiKey ?? "",
|
|
794
799
|
model: config.model,
|
|
800
|
+
baseUrl: config.baseUrl,
|
|
795
801
|
quotaPolicy: config.quotaPolicy,
|
|
796
802
|
vertexProject: config.vertexProject,
|
|
797
803
|
vertexRegion: config.vertexRegion,
|
|
@@ -895,6 +901,12 @@ async function withRetry3(fn, options = {}) {
|
|
|
895
901
|
|
|
896
902
|
// ../provider-openai/src/normalize.ts
|
|
897
903
|
var DEFAULT_MODEL2 = "gpt-5.4";
|
|
904
|
+
function createClient3(config) {
|
|
905
|
+
return new OpenAI({
|
|
906
|
+
apiKey: config.apiKey,
|
|
907
|
+
...config.baseUrl ? { baseURL: config.baseUrl } : {}
|
|
908
|
+
});
|
|
909
|
+
}
|
|
898
910
|
function validateConfig2(config) {
|
|
899
911
|
if (!config.apiKey || config.apiKey.length === 0) {
|
|
900
912
|
return { ok: false, provider: "openai", message: "missing api key" };
|
|
@@ -910,7 +922,7 @@ async function healthcheck2(config) {
|
|
|
910
922
|
const validation = validateConfig2(config);
|
|
911
923
|
if (!validation.ok) return validation;
|
|
912
924
|
try {
|
|
913
|
-
const client =
|
|
925
|
+
const client = createClient3(config);
|
|
914
926
|
const response = await withRetry3(
|
|
915
927
|
() => client.responses.create({
|
|
916
928
|
model: config.model ?? DEFAULT_MODEL2,
|
|
@@ -935,7 +947,7 @@ async function healthcheck2(config) {
|
|
|
935
947
|
}
|
|
936
948
|
async function executeTrackedQuery2(input) {
|
|
937
949
|
const model = input.config.model ?? DEFAULT_MODEL2;
|
|
938
|
-
const client =
|
|
950
|
+
const client = createClient3(input.config);
|
|
939
951
|
const webSearchTool = { type: "web_search" };
|
|
940
952
|
if (input.location) {
|
|
941
953
|
webSearchTool.user_location = {
|
|
@@ -1108,7 +1120,7 @@ function extractDomainFromUri2(uri) {
|
|
|
1108
1120
|
}
|
|
1109
1121
|
async function generateText2(prompt, config) {
|
|
1110
1122
|
const model = config.model ?? DEFAULT_MODEL2;
|
|
1111
|
-
const client =
|
|
1123
|
+
const client = createClient3(config);
|
|
1112
1124
|
const response = await withRetry3(
|
|
1113
1125
|
() => client.responses.create({
|
|
1114
1126
|
model,
|
|
@@ -1130,6 +1142,7 @@ function toOpenAIConfig(config) {
|
|
|
1130
1142
|
return {
|
|
1131
1143
|
apiKey: config.apiKey ?? "",
|
|
1132
1144
|
model: config.model,
|
|
1145
|
+
baseUrl: config.baseUrl,
|
|
1133
1146
|
quotaPolicy: config.quotaPolicy
|
|
1134
1147
|
};
|
|
1135
1148
|
}
|
|
@@ -1823,6 +1836,7 @@ var CDPProviderError = class extends Error {
|
|
|
1823
1836
|
this.code = code;
|
|
1824
1837
|
this.name = "CDPProviderError";
|
|
1825
1838
|
}
|
|
1839
|
+
code;
|
|
1826
1840
|
};
|
|
1827
1841
|
|
|
1828
1842
|
// ../provider-cdp/src/connection.ts
|
|
@@ -3031,6 +3045,8 @@ var ProviderExecutionGate = class {
|
|
|
3031
3045
|
this.maxConcurrency = maxConcurrency;
|
|
3032
3046
|
this.maxPerMinute = maxPerMinute;
|
|
3033
3047
|
}
|
|
3048
|
+
maxConcurrency;
|
|
3049
|
+
maxPerMinute;
|
|
3034
3050
|
window = [];
|
|
3035
3051
|
waiters = [];
|
|
3036
3052
|
rateLimitChain = Promise.resolve();
|
|
@@ -4933,7 +4949,7 @@ function buildDefaultDeps(registry) {
|
|
|
4933
4949
|
},
|
|
4934
4950
|
async embed(queries2) {
|
|
4935
4951
|
if (cfg.apiKey) {
|
|
4936
|
-
return embedQueries(queries2, { apiKey: cfg.apiKey });
|
|
4952
|
+
return embedQueries(queries2, { apiKey: cfg.apiKey, baseUrl: cfg.baseUrl });
|
|
4937
4953
|
}
|
|
4938
4954
|
throw new Error("Discovery currently requires a Gemini API key. Vertex-mode embeddings are not yet implemented.");
|
|
4939
4955
|
},
|
|
@@ -5761,7 +5777,7 @@ function readStoredGroundingSources(rawResponse) {
|
|
|
5761
5777
|
return result;
|
|
5762
5778
|
}
|
|
5763
5779
|
async function backfillInsightsCommand(project, opts) {
|
|
5764
|
-
const { IntelligenceService: IntelligenceService2 } = await import("./intelligence-service-
|
|
5780
|
+
const { IntelligenceService: IntelligenceService2 } = await import("./intelligence-service-CDVUUG7O.js");
|
|
5765
5781
|
const config = loadConfig();
|
|
5766
5782
|
const db = createClient(config.database);
|
|
5767
5783
|
migrate(db);
|
|
@@ -7179,6 +7195,11 @@ var RunCoordinator = class {
|
|
|
7179
7195
|
this.onInsightsGenerated = onInsightsGenerated;
|
|
7180
7196
|
this.onAeroEvent = onAeroEvent;
|
|
7181
7197
|
}
|
|
7198
|
+
db;
|
|
7199
|
+
notifier;
|
|
7200
|
+
intelligenceService;
|
|
7201
|
+
onInsightsGenerated;
|
|
7202
|
+
onAeroEvent;
|
|
7182
7203
|
async onRunCompleted(runId, projectId) {
|
|
7183
7204
|
const runRow = this.db.select().from(runs).where(eq14(runs.id, runId)).get();
|
|
7184
7205
|
const kind = runRow?.kind ?? RunKinds["answer-visibility"];
|
|
@@ -8843,6 +8864,8 @@ var ProviderExecutionGate2 = class {
|
|
|
8843
8864
|
this.maxConcurrency = maxConcurrency;
|
|
8844
8865
|
this.maxPerMinute = maxPerMinute;
|
|
8845
8866
|
}
|
|
8867
|
+
maxConcurrency;
|
|
8868
|
+
maxPerMinute;
|
|
8846
8869
|
window = [];
|
|
8847
8870
|
waiters = [];
|
|
8848
8871
|
rateLimitChain = Promise.resolve();
|
|
@@ -8904,6 +8927,7 @@ var SnapshotService = class {
|
|
|
8904
8927
|
constructor(registry) {
|
|
8905
8928
|
this.registry = registry;
|
|
8906
8929
|
}
|
|
8930
|
+
registry;
|
|
8907
8931
|
async createReport(input) {
|
|
8908
8932
|
const companyName = input.companyName.trim();
|
|
8909
8933
|
const domain = normalizeDomain(input.domain);
|
|
@@ -9452,11 +9476,16 @@ var BROWSER_ADAPTERS = [
|
|
|
9452
9476
|
var adapterMap = Object.fromEntries(
|
|
9453
9477
|
API_ADAPTERS.map((a) => [a.name, a])
|
|
9454
9478
|
);
|
|
9455
|
-
function summarizeProviderConfig(
|
|
9479
|
+
function summarizeProviderConfig(config) {
|
|
9456
9480
|
return {
|
|
9457
9481
|
configured: Boolean(config?.apiKey || config?.baseUrl),
|
|
9458
9482
|
model: config?.model ?? null,
|
|
9459
|
-
baseUrl
|
|
9483
|
+
// baseUrl is surfaced for ALL providers, not just local — gemini/openai now
|
|
9484
|
+
// honor a custom endpoint, so repointing one must show in the settings
|
|
9485
|
+
// summary AND produce an audit diff. Omitting it for API providers would let
|
|
9486
|
+
// an endpoint redirect (a credential-exfiltration vector on a box where the
|
|
9487
|
+
// provider key is the carrier) happen with no audit trail.
|
|
9488
|
+
baseUrl: config?.baseUrl ?? null,
|
|
9460
9489
|
quota: { ...config?.quota ?? DEFAULT_QUOTA }
|
|
9461
9490
|
};
|
|
9462
9491
|
}
|
|
@@ -10330,7 +10359,7 @@ async function createServer(opts) {
|
|
|
10330
10359
|
if (!adapterMap[name]) return null;
|
|
10331
10360
|
if (!opts.config.providers) opts.config.providers = {};
|
|
10332
10361
|
const existing = opts.config.providers[name];
|
|
10333
|
-
const beforeConfig = summarizeProviderConfig(
|
|
10362
|
+
const beforeConfig = summarizeProviderConfig(existing);
|
|
10334
10363
|
const mergedQuota = incomingQuota ? { ...existing?.quota ?? DEFAULT_QUOTA, ...incomingQuota } : existing?.quota;
|
|
10335
10364
|
opts.config.providers[name] = {
|
|
10336
10365
|
apiKey: apiKey || existing?.apiKey,
|
|
@@ -10369,7 +10398,7 @@ async function createServer(opts) {
|
|
|
10369
10398
|
entry.vertexConfigured = !!opts.config.providers?.[name]?.vertexProject;
|
|
10370
10399
|
}
|
|
10371
10400
|
}
|
|
10372
|
-
const afterConfig = summarizeProviderConfig(
|
|
10401
|
+
const afterConfig = summarizeProviderConfig(opts.config.providers[name]);
|
|
10373
10402
|
if (JSON.stringify(beforeConfig) !== JSON.stringify(afterConfig)) {
|
|
10374
10403
|
const diff = JSON.stringify({
|
|
10375
10404
|
before: existing ? beforeConfig : null,
|
package/dist/cli.js
CHANGED
|
@@ -27,7 +27,7 @@ import {
|
|
|
27
27
|
setTelemetrySource,
|
|
28
28
|
showFirstRunNotice,
|
|
29
29
|
trackEvent
|
|
30
|
-
} from "./chunk-
|
|
30
|
+
} from "./chunk-QKTIP6GC.js";
|
|
31
31
|
import {
|
|
32
32
|
CliError,
|
|
33
33
|
EXIT_SYSTEM_ERROR,
|
|
@@ -44,7 +44,7 @@ import {
|
|
|
44
44
|
saveConfig,
|
|
45
45
|
saveConfigPatch,
|
|
46
46
|
usageError
|
|
47
|
-
} from "./chunk-
|
|
47
|
+
} from "./chunk-XI6YSTGE.js";
|
|
48
48
|
import {
|
|
49
49
|
apiKeys,
|
|
50
50
|
createClient,
|
|
@@ -52,7 +52,7 @@ import {
|
|
|
52
52
|
projects,
|
|
53
53
|
queries,
|
|
54
54
|
renderReportHtml
|
|
55
|
-
} from "./chunk-
|
|
55
|
+
} from "./chunk-3WXARKUE.js";
|
|
56
56
|
import {
|
|
57
57
|
CcReleaseSyncStatuses,
|
|
58
58
|
CheckScopes,
|
|
@@ -72,7 +72,7 @@ import {
|
|
|
72
72
|
providerQuotaPolicySchema,
|
|
73
73
|
resolveProviderInput,
|
|
74
74
|
winnabilityClassSchema
|
|
75
|
-
} from "./chunk-
|
|
75
|
+
} from "./chunk-KPN22EWK.js";
|
|
76
76
|
|
|
77
77
|
// src/cli.ts
|
|
78
78
|
import { pathToFileURL } from "url";
|
|
@@ -8305,6 +8305,9 @@ var PdfWriter = class {
|
|
|
8305
8305
|
this.bold = bold;
|
|
8306
8306
|
this.addPage();
|
|
8307
8307
|
}
|
|
8308
|
+
doc;
|
|
8309
|
+
regular;
|
|
8310
|
+
bold;
|
|
8308
8311
|
usableWidth = PAGE_WIDTH - MARGIN * 2;
|
|
8309
8312
|
page;
|
|
8310
8313
|
y = 0;
|
|
@@ -9633,6 +9636,7 @@ var envSchema = z.object({
|
|
|
9633
9636
|
// Gemini
|
|
9634
9637
|
GEMINI_API_KEY: z.string().optional(),
|
|
9635
9638
|
GEMINI_MODEL: z.string().optional(),
|
|
9639
|
+
GEMINI_BASE_URL: z.string().optional(),
|
|
9636
9640
|
GEMINI_MAX_CONCURRENCY: z.coerce.number().int().positive().default(2),
|
|
9637
9641
|
GEMINI_MAX_REQUESTS_PER_MINUTE: z.coerce.number().int().positive().default(10),
|
|
9638
9642
|
GEMINI_MAX_REQUESTS_PER_DAY: z.coerce.number().int().positive().default(1e3),
|
|
@@ -9643,6 +9647,7 @@ var envSchema = z.object({
|
|
|
9643
9647
|
// OpenAI
|
|
9644
9648
|
OPENAI_API_KEY: z.string().optional(),
|
|
9645
9649
|
OPENAI_MODEL: z.string().optional(),
|
|
9650
|
+
OPENAI_BASE_URL: z.string().optional(),
|
|
9646
9651
|
OPENAI_MAX_CONCURRENCY: z.coerce.number().int().positive().default(2),
|
|
9647
9652
|
OPENAI_MAX_REQUESTS_PER_MINUTE: z.coerce.number().int().positive().default(10),
|
|
9648
9653
|
OPENAI_MAX_REQUESTS_PER_DAY: z.coerce.number().int().positive().default(1e3),
|
|
@@ -9669,11 +9674,13 @@ var bootstrapEnvSchema = z.object({
|
|
|
9669
9674
|
CANONRY_DATABASE_PATH: z.string().optional(),
|
|
9670
9675
|
GEMINI_API_KEY: z.string().optional(),
|
|
9671
9676
|
GEMINI_MODEL: z.string().optional(),
|
|
9677
|
+
GEMINI_BASE_URL: z.string().optional(),
|
|
9672
9678
|
GEMINI_VERTEX_PROJECT: z.string().optional(),
|
|
9673
9679
|
GEMINI_VERTEX_REGION: z.string().optional(),
|
|
9674
9680
|
GEMINI_VERTEX_CREDENTIALS: z.string().optional(),
|
|
9675
9681
|
OPENAI_API_KEY: z.string().optional(),
|
|
9676
9682
|
OPENAI_MODEL: z.string().optional(),
|
|
9683
|
+
OPENAI_BASE_URL: z.string().optional(),
|
|
9677
9684
|
ANTHROPIC_API_KEY: z.string().optional(),
|
|
9678
9685
|
ANTHROPIC_MODEL: z.string().optional(),
|
|
9679
9686
|
PERPLEXITY_API_KEY: z.string().optional(),
|
|
@@ -9692,6 +9699,7 @@ function getBootstrapEnv(source, overrides) {
|
|
|
9692
9699
|
providers.gemini = {
|
|
9693
9700
|
apiKey: parsed.GEMINI_API_KEY ?? "",
|
|
9694
9701
|
model: parsed.GEMINI_MODEL || "gemini-2.5-flash",
|
|
9702
|
+
baseUrl: parsed.GEMINI_BASE_URL,
|
|
9695
9703
|
quota: providerQuotaPolicySchema.parse({
|
|
9696
9704
|
maxConcurrency: 2,
|
|
9697
9705
|
maxRequestsPerMinute: 10,
|
|
@@ -9706,6 +9714,7 @@ function getBootstrapEnv(source, overrides) {
|
|
|
9706
9714
|
providers.openai = {
|
|
9707
9715
|
apiKey: parsed.OPENAI_API_KEY,
|
|
9708
9716
|
model: parsed.OPENAI_MODEL || "gpt-5.4",
|
|
9717
|
+
baseUrl: parsed.OPENAI_BASE_URL,
|
|
9709
9718
|
quota: providerQuotaPolicySchema.parse({
|
|
9710
9719
|
maxConcurrency: 2,
|
|
9711
9720
|
maxRequestsPerMinute: 10,
|
package/dist/index.js
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import {
|
|
2
2
|
createServer
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-QKTIP6GC.js";
|
|
4
4
|
import {
|
|
5
5
|
loadConfig
|
|
6
|
-
} from "./chunk-
|
|
7
|
-
import "./chunk-
|
|
8
|
-
import "./chunk-
|
|
6
|
+
} from "./chunk-XI6YSTGE.js";
|
|
7
|
+
import "./chunk-3WXARKUE.js";
|
|
8
|
+
import "./chunk-KPN22EWK.js";
|
|
9
9
|
export {
|
|
10
10
|
createServer,
|
|
11
11
|
loadConfig
|
package/dist/mcp.js
CHANGED
|
@@ -3,8 +3,8 @@ import {
|
|
|
3
3
|
PACKAGE_VERSION,
|
|
4
4
|
canonryMcpTools,
|
|
5
5
|
createApiClient
|
|
6
|
-
} from "./chunk-
|
|
7
|
-
import "./chunk-
|
|
6
|
+
} from "./chunk-XI6YSTGE.js";
|
|
7
|
+
import "./chunk-KPN22EWK.js";
|
|
8
8
|
|
|
9
9
|
// src/mcp/cli.ts
|
|
10
10
|
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ainyc/canonry",
|
|
3
|
-
"version": "4.
|
|
3
|
+
"version": "4.78.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Agent-first open-source AEO operating platform - track how answer engines cite your domain",
|
|
6
6
|
"license": "FSL-1.1-ALv2",
|
|
@@ -37,8 +37,8 @@
|
|
|
37
37
|
},
|
|
38
38
|
"dependencies": {
|
|
39
39
|
"@ainyc/aeo-audit": "3.0.0",
|
|
40
|
-
"@anthropic-ai/sdk": "^0.
|
|
41
|
-
"@fastify/static": "^
|
|
40
|
+
"@anthropic-ai/sdk": "^0.91.1",
|
|
41
|
+
"@fastify/static": "^9.1.1",
|
|
42
42
|
"@google/genai": "^1.46.0",
|
|
43
43
|
"@mariozechner/pi-agent-core": "0.67.6",
|
|
44
44
|
"@mariozechner/pi-ai": "0.67.6",
|
|
@@ -63,25 +63,25 @@
|
|
|
63
63
|
"tsup": "^8.5.1",
|
|
64
64
|
"tsx": "^4.19.0",
|
|
65
65
|
"@ainyc/canonry-api-client": "0.0.0",
|
|
66
|
+
"@ainyc/canonry-config": "0.0.0",
|
|
66
67
|
"@ainyc/canonry-api-routes": "0.0.0",
|
|
67
68
|
"@ainyc/canonry-contracts": "0.0.0",
|
|
68
69
|
"@ainyc/canonry-db": "0.0.0",
|
|
69
70
|
"@ainyc/canonry-integration-bing": "0.0.0",
|
|
70
|
-
"@ainyc/canonry-config": "0.0.0",
|
|
71
71
|
"@ainyc/canonry-integration-cloud-run": "0.0.0",
|
|
72
72
|
"@ainyc/canonry-integration-commoncrawl": "0.0.0",
|
|
73
73
|
"@ainyc/canonry-integration-google": "0.0.0",
|
|
74
|
-
"@ainyc/canonry-integration-google-places": "0.0.0",
|
|
75
|
-
"@ainyc/canonry-integration-traffic": "0.0.0",
|
|
76
74
|
"@ainyc/canonry-integration-google-business-profile": "0.0.0",
|
|
77
|
-
"@ainyc/canonry-
|
|
78
|
-
"@ainyc/canonry-
|
|
75
|
+
"@ainyc/canonry-integration-traffic": "0.0.0",
|
|
76
|
+
"@ainyc/canonry-integration-google-places": "0.0.0",
|
|
79
77
|
"@ainyc/canonry-integration-wordpress": "0.0.0",
|
|
80
|
-
"@ainyc/canonry-
|
|
78
|
+
"@ainyc/canonry-intelligence": "0.0.0",
|
|
81
79
|
"@ainyc/canonry-provider-claude": "0.0.0",
|
|
80
|
+
"@ainyc/canonry-provider-cdp": "0.0.0",
|
|
82
81
|
"@ainyc/canonry-provider-openai": "0.0.0",
|
|
83
82
|
"@ainyc/canonry-provider-perplexity": "0.0.0",
|
|
84
|
-
"@ainyc/canonry-provider-local": "0.0.0"
|
|
83
|
+
"@ainyc/canonry-provider-local": "0.0.0",
|
|
84
|
+
"@ainyc/canonry-provider-gemini": "0.0.0"
|
|
85
85
|
},
|
|
86
86
|
"scripts": {
|
|
87
87
|
"build": "tsx scripts/copy-agent-assets.ts && tsup && tsx build-web.ts",
|