@ainyc/canonry 1.32.0 → 1.33.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/{index-r6biprHB.css → index-B5Cg2H9M.css} +1 -1
- package/assets/assets/index-BiIPqZJb.js +246 -0
- package/assets/index.html +2 -2
- package/dist/{chunk-5Q6LISDM.js → chunk-WRNSBFNQ.js} +47 -19
- package/dist/cli.js +5 -5
- package/dist/index.js +1 -1
- package/package.json +7 -7
- package/assets/assets/index-BuSiyI7z.js +0 -246
package/assets/index.html
CHANGED
|
@@ -12,8 +12,8 @@
|
|
|
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-
|
|
16
|
-
<link rel="stylesheet" crossorigin href="./assets/index-
|
|
15
|
+
<script type="module" crossorigin src="./assets/index-BiIPqZJb.js"></script>
|
|
16
|
+
<link rel="stylesheet" crossorigin href="./assets/index-B5Cg2H9M.css">
|
|
17
17
|
</head>
|
|
18
18
|
<body>
|
|
19
19
|
<div id="root"></div>
|
|
@@ -816,6 +816,7 @@ var querySnapshotDtoSchema = z8.object({
|
|
|
816
816
|
citedDomains: z8.array(z8.string()).default([]),
|
|
817
817
|
competitorOverlap: z8.array(z8.string()).default([]),
|
|
818
818
|
recommendedCompetitors: z8.array(z8.string()).default([]),
|
|
819
|
+
matchedTerms: z8.array(z8.string()).default([]),
|
|
819
820
|
groundingSources: z8.array(groundingSourceSchema).default([]),
|
|
820
821
|
searchQueries: z8.array(z8.string()).default([]),
|
|
821
822
|
model: z8.string().nullable().optional(),
|
|
@@ -1093,30 +1094,39 @@ var GENERIC_TOKENS = /* @__PURE__ */ new Set([
|
|
|
1093
1094
|
"systems",
|
|
1094
1095
|
"tech"
|
|
1095
1096
|
]);
|
|
1096
|
-
function
|
|
1097
|
-
if (!answerText) return false;
|
|
1097
|
+
function extractAnswerMentions(answerText, displayName, domains) {
|
|
1098
|
+
if (!answerText) return { mentioned: false, matchedTerms: [] };
|
|
1099
|
+
const matchedTerms = [];
|
|
1098
1100
|
const lowerAnswer = answerText.toLowerCase();
|
|
1099
1101
|
for (const domain of domains) {
|
|
1100
1102
|
const normalizedDomain = normalizeProjectDomain(domain);
|
|
1101
1103
|
if (!normalizedDomain || !normalizedDomain.includes(".")) continue;
|
|
1102
|
-
if (domainMentioned(lowerAnswer, normalizedDomain))
|
|
1104
|
+
if (domainMentioned(lowerAnswer, normalizedDomain)) {
|
|
1105
|
+
matchedTerms.push(normalizedDomain);
|
|
1106
|
+
}
|
|
1103
1107
|
}
|
|
1104
1108
|
const normalizedDisplayName = normalizeText(displayName);
|
|
1105
1109
|
if (normalizedDisplayName && normalizeText(answerText).includes(normalizedDisplayName)) {
|
|
1106
|
-
|
|
1110
|
+
matchedTerms.push(displayName);
|
|
1107
1111
|
}
|
|
1108
1112
|
const tokens = collectDistinctiveTokens(displayName, domains);
|
|
1109
|
-
|
|
1110
|
-
|
|
1113
|
+
let tokenMatches = 0;
|
|
1114
|
+
const matchedTokens = [];
|
|
1111
1115
|
for (const token of tokens) {
|
|
1112
1116
|
if (new RegExp(`\\b${escapeRegExp(token)}\\b`).test(lowerAnswer)) {
|
|
1113
|
-
|
|
1117
|
+
tokenMatches++;
|
|
1118
|
+
matchedTokens.push(token);
|
|
1114
1119
|
}
|
|
1115
1120
|
}
|
|
1116
|
-
|
|
1117
|
-
|
|
1121
|
+
const tokenThresholdMet = tokens.length > 0 && (tokens.length === 1 && tokenMatches >= 1 || tokenMatches >= Math.min(2, tokens.length));
|
|
1122
|
+
if (tokenThresholdMet) {
|
|
1123
|
+
matchedTerms.push(...matchedTokens);
|
|
1118
1124
|
}
|
|
1119
|
-
|
|
1125
|
+
const unique = [...new Set(matchedTerms)];
|
|
1126
|
+
return { mentioned: unique.length > 0, matchedTerms: unique };
|
|
1127
|
+
}
|
|
1128
|
+
function determineAnswerMentioned(answerText, displayName, domains) {
|
|
1129
|
+
return extractAnswerMentions(answerText, displayName, domains).mentioned;
|
|
1120
1130
|
}
|
|
1121
1131
|
function visibilityStateFromAnswerMentioned(answerMentioned) {
|
|
1122
1132
|
return answerMentioned ? "visible" : "not-visible";
|
|
@@ -1930,17 +1940,27 @@ function writeAuditLog(db, entry) {
|
|
|
1930
1940
|
createdAt: now
|
|
1931
1941
|
}).run();
|
|
1932
1942
|
}
|
|
1933
|
-
function
|
|
1943
|
+
function resolveSnapshotMentionResult(snapshot, project) {
|
|
1944
|
+
if (snapshot.answerText) {
|
|
1945
|
+
const domains = effectiveDomains({
|
|
1946
|
+
canonicalDomain: project.canonicalDomain,
|
|
1947
|
+
ownedDomains: normalizeOwnedDomains(project.ownedDomains)
|
|
1948
|
+
});
|
|
1949
|
+
return extractAnswerMentions(snapshot.answerText, project.displayName, domains);
|
|
1950
|
+
}
|
|
1934
1951
|
if (typeof snapshot.answerMentioned === "boolean") {
|
|
1935
|
-
return snapshot.answerMentioned;
|
|
1952
|
+
return { mentioned: snapshot.answerMentioned, matchedTerms: [] };
|
|
1936
1953
|
}
|
|
1937
|
-
return
|
|
1938
|
-
|
|
1939
|
-
|
|
1940
|
-
|
|
1954
|
+
return { mentioned: false, matchedTerms: [] };
|
|
1955
|
+
}
|
|
1956
|
+
function resolveSnapshotAnswerMentioned(snapshot, project) {
|
|
1957
|
+
return resolveSnapshotMentionResult(snapshot, project).mentioned;
|
|
1941
1958
|
}
|
|
1942
1959
|
function resolveSnapshotVisibilityState(snapshot, project) {
|
|
1943
|
-
return visibilityStateFromAnswerMentioned(
|
|
1960
|
+
return visibilityStateFromAnswerMentioned(resolveSnapshotMentionResult(snapshot, project).mentioned);
|
|
1961
|
+
}
|
|
1962
|
+
function resolveSnapshotMatchedTerms(snapshot, project) {
|
|
1963
|
+
return resolveSnapshotMentionResult(snapshot, project).matchedTerms;
|
|
1944
1964
|
}
|
|
1945
1965
|
function normalizeOwnedDomains(value) {
|
|
1946
1966
|
if (Array.isArray(value)) return value.filter((item) => typeof item === "string");
|
|
@@ -2645,6 +2665,7 @@ async function runRoutes(app, opts) {
|
|
|
2645
2665
|
citedDomains: parseJsonColumn(s.citedDomains, []),
|
|
2646
2666
|
competitorOverlap: parseJsonColumn(s.competitorOverlap, []),
|
|
2647
2667
|
recommendedCompetitors: parseJsonColumn(s.recommendedCompetitors, []),
|
|
2668
|
+
matchedTerms: project ? resolveSnapshotMatchedTerms(s, project) : [],
|
|
2648
2669
|
model: s.model ?? rawParsed.model,
|
|
2649
2670
|
location: s.location,
|
|
2650
2671
|
groundingSources: rawParsed.groundingSources,
|
|
@@ -11280,7 +11301,7 @@ var CDPConnectionManager = class {
|
|
|
11280
11301
|
await sleep(1500);
|
|
11281
11302
|
} catch (err) {
|
|
11282
11303
|
throw new CDPProviderError(
|
|
11283
|
-
"
|
|
11304
|
+
"CDP_TARGET_SELECTOR_FAILED",
|
|
11284
11305
|
`Failed to navigate to ${target.newConversationUrl}: ${err instanceof Error ? err.message : String(err)}`
|
|
11285
11306
|
);
|
|
11286
11307
|
}
|
|
@@ -11769,10 +11790,11 @@ async function healthcheck5(config) {
|
|
|
11769
11790
|
async function executeTrackedQuery5(input) {
|
|
11770
11791
|
const model = input.config.model ?? DEFAULT_MODEL5;
|
|
11771
11792
|
const client = new OpenAI3({ apiKey: input.config.apiKey, baseURL: BASE_URL });
|
|
11793
|
+
const prompt = buildPrompt4(input.keyword, input.location);
|
|
11772
11794
|
const response = await client.chat.completions.create({
|
|
11773
11795
|
model,
|
|
11774
11796
|
messages: [
|
|
11775
|
-
{ role: "user", content:
|
|
11797
|
+
{ role: "user", content: prompt }
|
|
11776
11798
|
]
|
|
11777
11799
|
});
|
|
11778
11800
|
const rawResponse = responseToRecord4(response);
|
|
@@ -11800,6 +11822,12 @@ function normalizeResult6(raw) {
|
|
|
11800
11822
|
searchQueries: raw.searchQueries
|
|
11801
11823
|
};
|
|
11802
11824
|
}
|
|
11825
|
+
function buildPrompt4(keyword, location) {
|
|
11826
|
+
if (location) {
|
|
11827
|
+
return `${keyword} (searching from ${location.city}, ${location.region}, ${location.country})`;
|
|
11828
|
+
}
|
|
11829
|
+
return keyword;
|
|
11830
|
+
}
|
|
11803
11831
|
function extractCitations(rawResponse) {
|
|
11804
11832
|
if (Array.isArray(rawResponse.citations)) {
|
|
11805
11833
|
return rawResponse.citations.filter((c) => typeof c === "string");
|
package/dist/cli.js
CHANGED
|
@@ -26,7 +26,7 @@ import {
|
|
|
26
26
|
setGoogleAuthConfig,
|
|
27
27
|
showFirstRunNotice,
|
|
28
28
|
trackEvent
|
|
29
|
-
} from "./chunk-
|
|
29
|
+
} from "./chunk-WRNSBFNQ.js";
|
|
30
30
|
|
|
31
31
|
// src/cli.ts
|
|
32
32
|
import { pathToFileURL } from "url";
|
|
@@ -1776,10 +1776,10 @@ Open this URL in your browser to authorize Google ${opts.type.toUpperCase()} acc
|
|
|
1776
1776
|
console.log("(Ensure this URI is listed in your Google Cloud Console OAuth client's authorized redirect URIs)\n");
|
|
1777
1777
|
}
|
|
1778
1778
|
try {
|
|
1779
|
-
const {
|
|
1779
|
+
const { spawn: spawn2 } = await import("child_process");
|
|
1780
1780
|
const platform = process.platform;
|
|
1781
|
-
const cmd = platform === "darwin" ? "open" : platform === "win32" ? "start" : "xdg-open";
|
|
1782
|
-
|
|
1781
|
+
const [cmd, ...extraArgs] = platform === "darwin" ? ["open", authUrl] : platform === "win32" ? ["cmd", "/c", "start", "", authUrl] : ["xdg-open", authUrl];
|
|
1782
|
+
spawn2(cmd, [...extraArgs], { detached: true, stdio: "ignore" }).unref();
|
|
1783
1783
|
console.log("(Browser opened automatically)");
|
|
1784
1784
|
} catch {
|
|
1785
1785
|
console.log("(Could not open browser automatically \u2014 please copy the URL above)");
|
|
@@ -4025,7 +4025,7 @@ async function showSchedule(project, format) {
|
|
|
4025
4025
|
async function enableSchedule(project, format) {
|
|
4026
4026
|
const client = getClient14();
|
|
4027
4027
|
const current = await client.getSchedule(project);
|
|
4028
|
-
const body = { timezone: current.timezone };
|
|
4028
|
+
const body = { timezone: current.timezone, enabled: true };
|
|
4029
4029
|
if (current.preset) body.preset = current.preset;
|
|
4030
4030
|
else body.cron = current.cronExpr;
|
|
4031
4031
|
if (current.providers.length) body.providers = current.providers;
|
package/dist/index.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ainyc/canonry",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.33.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "The ultimate open-source AEO monitoring tool - track how answer engines cite your domain",
|
|
6
6
|
"license": "FSL-1.1-ALv2",
|
|
@@ -55,18 +55,18 @@
|
|
|
55
55
|
"tsup": "^8.5.1",
|
|
56
56
|
"tsx": "^4.19.0",
|
|
57
57
|
"@ainyc/canonry-api-routes": "0.0.0",
|
|
58
|
-
"@ainyc/canonry-config": "0.0.0",
|
|
59
58
|
"@ainyc/canonry-contracts": "0.0.0",
|
|
60
|
-
"@ainyc/canonry-
|
|
59
|
+
"@ainyc/canonry-config": "0.0.0",
|
|
61
60
|
"@ainyc/canonry-integration-bing": "0.0.0",
|
|
62
|
-
"@ainyc/canonry-
|
|
63
|
-
"@ainyc/canonry-provider-cdp": "0.0.0",
|
|
61
|
+
"@ainyc/canonry-integration-google": "0.0.0",
|
|
64
62
|
"@ainyc/canonry-integration-wordpress": "0.0.0",
|
|
63
|
+
"@ainyc/canonry-provider-cdp": "0.0.0",
|
|
65
64
|
"@ainyc/canonry-provider-claude": "0.0.0",
|
|
65
|
+
"@ainyc/canonry-db": "0.0.0",
|
|
66
66
|
"@ainyc/canonry-provider-gemini": "0.0.0",
|
|
67
67
|
"@ainyc/canonry-provider-local": "0.0.0",
|
|
68
|
-
"@ainyc/canonry-provider-
|
|
69
|
-
"@ainyc/canonry-provider-
|
|
68
|
+
"@ainyc/canonry-provider-perplexity": "0.0.0",
|
|
69
|
+
"@ainyc/canonry-provider-openai": "0.0.0"
|
|
70
70
|
},
|
|
71
71
|
"scripts": {
|
|
72
72
|
"build": "tsup && tsx build-web.ts",
|