@ainyc/canonry 4.2.2 → 4.7.2
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/reporting.md +2 -1
- package/assets/agent-workspace/skills/canonry-setup/references/canonry-cli.md +1 -1
- package/assets/assets/index-Ca3kZYGw.js +302 -0
- package/assets/assets/{index-D7T5wSBj.css → index-DAS6pOry.css} +1 -1
- package/assets/index.html +2 -2
- package/dist/{chunk-HJZY4EOE.js → chunk-DVTPGC6O.js} +816 -119
- package/dist/{chunk-7YSI4GFA.js → chunk-OOADR2Q5.js} +10 -4
- package/dist/{chunk-SR7TGHHG.js → chunk-VDEMEI64.js} +2 -2
- package/dist/{chunk-T2I6AO7D.js → chunk-XAW66QUX.js} +77 -1
- package/dist/cli.js +20 -10
- package/dist/index.js +4 -4
- package/dist/{intelligence-service-CQGAXKKN.js → intelligence-service-ABHO5HHA.js} +2 -2
- package/dist/mcp.js +2 -2
- package/package.json +8 -8
- package/assets/assets/index-DoJfQkim.js +0 -302
|
@@ -4,10 +4,11 @@ import {
|
|
|
4
4
|
RunKinds,
|
|
5
5
|
__export,
|
|
6
6
|
brandLabelFromDomain,
|
|
7
|
-
|
|
7
|
+
categorizeSourceWithCompetitors,
|
|
8
|
+
categoryLabel,
|
|
8
9
|
determineAnswerMentioned,
|
|
9
10
|
normalizeProjectDomain
|
|
10
|
-
} from "./chunk-
|
|
11
|
+
} from "./chunk-XAW66QUX.js";
|
|
11
12
|
|
|
12
13
|
// src/intelligence-service.ts
|
|
13
14
|
import { eq, desc, asc, and, or, inArray } from "drizzle-orm";
|
|
@@ -2581,8 +2582,13 @@ function buildAiSourceOrigin(snapshots, projectDomains, competitorDomains, topDo
|
|
|
2581
2582
|
for (const snap of snapshots) {
|
|
2582
2583
|
for (const raw of snap.citedDomains) {
|
|
2583
2584
|
if (citedDomainBelongsToProject(raw, projectDomains)) continue;
|
|
2584
|
-
const { category,
|
|
2585
|
-
|
|
2585
|
+
const { category, domain } = categorizeSourceWithCompetitors(
|
|
2586
|
+
raw,
|
|
2587
|
+
competitorDomains,
|
|
2588
|
+
citedDomainBelongsToProject
|
|
2589
|
+
);
|
|
2590
|
+
const bucketLabel = categoryLabel(category);
|
|
2591
|
+
const cat = categoryCounts.get(category) ?? { label: bucketLabel, count: 0 };
|
|
2586
2592
|
cat.count++;
|
|
2587
2593
|
categoryCounts.set(category, cat);
|
|
2588
2594
|
domainCounts.set(domain, (domainCounts.get(domain) ?? 0) + 1);
|
|
@@ -12,7 +12,7 @@ import {
|
|
|
12
12
|
queryGenerateRequestSchema,
|
|
13
13
|
runTriggerRequestSchema,
|
|
14
14
|
scheduleUpsertRequestSchema
|
|
15
|
-
} from "./chunk-
|
|
15
|
+
} from "./chunk-XAW66QUX.js";
|
|
16
16
|
|
|
17
17
|
// src/config.ts
|
|
18
18
|
import fs from "fs";
|
|
@@ -1176,7 +1176,7 @@ var canonryMcpTools = [
|
|
|
1176
1176
|
defineTool({
|
|
1177
1177
|
name: "canonry_report",
|
|
1178
1178
|
title: "Get aggregated AEO report",
|
|
1179
|
-
description: "Returns the full
|
|
1179
|
+
description: "Returns the full canonical AEO report bundle for a project \u2014 executive summary, client summary, agency diagnostics, action plan, per-query \xD7 per-provider citation matrix, competitor landscape, AI citation sources, GSC/GA4 performance, social and AI referrals, indexing health, citations trend, prioritized insights, and recommended next steps. Same payload `canonry report <project>` consumes to render audience-specific HTML.",
|
|
1180
1180
|
access: "read",
|
|
1181
1181
|
tier: "monitoring",
|
|
1182
1182
|
inputSchema: projectInputSchema,
|
|
@@ -42,6 +42,39 @@ var locationContextSchema = z.object({
|
|
|
42
42
|
country: z.string().length(2),
|
|
43
43
|
timezone: z.string().optional()
|
|
44
44
|
});
|
|
45
|
+
var PROVIDER_LOCATION_HANDLING = {
|
|
46
|
+
gemini: {
|
|
47
|
+
treatment: "prompt",
|
|
48
|
+
description: "Location appended to the query text the Gemini model receives."
|
|
49
|
+
},
|
|
50
|
+
perplexity: {
|
|
51
|
+
treatment: "prompt",
|
|
52
|
+
description: "Location appended to the query text the Perplexity model receives."
|
|
53
|
+
},
|
|
54
|
+
local: {
|
|
55
|
+
treatment: "prompt",
|
|
56
|
+
description: "Location appended to the system message sent to the local model."
|
|
57
|
+
},
|
|
58
|
+
openai: {
|
|
59
|
+
treatment: "request-param",
|
|
60
|
+
description: "Location sent as a structured `user_location` field on OpenAI\u2019s web_search_preview tool."
|
|
61
|
+
},
|
|
62
|
+
claude: {
|
|
63
|
+
treatment: "request-param",
|
|
64
|
+
description: "Location sent as a structured `user_location` field on Anthropic\u2019s web_search_20250305 tool."
|
|
65
|
+
},
|
|
66
|
+
"cdp:chatgpt": {
|
|
67
|
+
treatment: "browser-geo",
|
|
68
|
+
description: "CDP relies on the browser session\u2019s own geolocation; canonry\u2019s configured location is not forwarded."
|
|
69
|
+
}
|
|
70
|
+
};
|
|
71
|
+
var UNKNOWN_PROVIDER_HANDLING = {
|
|
72
|
+
treatment: "ignored",
|
|
73
|
+
description: "No documented location handling for this provider \u2014 assume the configured location was not applied."
|
|
74
|
+
};
|
|
75
|
+
function getProviderLocationHandling(provider) {
|
|
76
|
+
return PROVIDER_LOCATION_HANDLING[provider] ?? UNKNOWN_PROVIDER_HANDLING;
|
|
77
|
+
}
|
|
45
78
|
|
|
46
79
|
// ../contracts/src/run.ts
|
|
47
80
|
var runStatusSchema = z2.enum(["queued", "running", "completed", "partial", "failed", "cancelled"]);
|
|
@@ -1030,6 +1063,29 @@ function windowCutoff(window) {
|
|
|
1030
1063
|
|
|
1031
1064
|
// ../contracts/src/source-categories.ts
|
|
1032
1065
|
var SOURCE_CATEGORY_RULES = [
|
|
1066
|
+
// Directories, marketplaces & review platforms — generic across industries.
|
|
1067
|
+
// Industry-specific directories (NRCA, GAF, etc.) intentionally omitted;
|
|
1068
|
+
// they would slip past for the next vertical and create maintenance churn.
|
|
1069
|
+
{ pattern: "yelp.com", category: "directory", label: "Yelp" },
|
|
1070
|
+
{ pattern: "angi.com", category: "directory", label: "Angi" },
|
|
1071
|
+
{ pattern: "angieslist.com", category: "directory", label: "Angi" },
|
|
1072
|
+
{ pattern: "homeadvisor.com", category: "directory", label: "HomeAdvisor" },
|
|
1073
|
+
{ pattern: "bbb.org", category: "directory", label: "Better Business Bureau" },
|
|
1074
|
+
{ pattern: "trustpilot.com", category: "directory", label: "Trustpilot" },
|
|
1075
|
+
{ pattern: "houzz.com", category: "directory", label: "Houzz" },
|
|
1076
|
+
{ pattern: "thumbtack.com", category: "directory", label: "Thumbtack" },
|
|
1077
|
+
{ pattern: "nextdoor.com", category: "directory", label: "Nextdoor" },
|
|
1078
|
+
{ pattern: "yellowpages.com", category: "directory", label: "Yellow Pages" },
|
|
1079
|
+
{ pattern: "manta.com", category: "directory", label: "Manta" },
|
|
1080
|
+
{ pattern: "foursquare.com", category: "directory", label: "Foursquare" },
|
|
1081
|
+
{ pattern: "g2.com", category: "directory", label: "G2" },
|
|
1082
|
+
{ pattern: "capterra.com", category: "directory", label: "Capterra" },
|
|
1083
|
+
{ pattern: "getapp.com", category: "directory", label: "GetApp" },
|
|
1084
|
+
{ pattern: "softwareadvice.com", category: "directory", label: "Software Advice" },
|
|
1085
|
+
{ pattern: "trustradius.com", category: "directory", label: "TrustRadius" },
|
|
1086
|
+
{ pattern: "producthunt.com", category: "directory", label: "Product Hunt" },
|
|
1087
|
+
{ pattern: "glassdoor.com", category: "directory", label: "Glassdoor" },
|
|
1088
|
+
{ pattern: "indeed.com", category: "directory", label: "Indeed" },
|
|
1033
1089
|
// Forums
|
|
1034
1090
|
{ pattern: "reddit.com", category: "forum", label: "Reddit" },
|
|
1035
1091
|
{ pattern: "quora.com", category: "forum", label: "Quora" },
|
|
@@ -1090,6 +1146,8 @@ var SOURCE_CATEGORY_RULES = [
|
|
|
1090
1146
|
{ pattern: ".edu", category: "academic", label: "Academic (.edu)" }
|
|
1091
1147
|
];
|
|
1092
1148
|
var CATEGORY_LABELS = {
|
|
1149
|
+
competitor: "Tracked competitors",
|
|
1150
|
+
directory: "Directories & review sites",
|
|
1093
1151
|
social: "Social Media",
|
|
1094
1152
|
forum: "Forums & Q&A",
|
|
1095
1153
|
news: "News & Media",
|
|
@@ -1098,7 +1156,7 @@ var CATEGORY_LABELS = {
|
|
|
1098
1156
|
ecommerce: "E-commerce",
|
|
1099
1157
|
video: "Video",
|
|
1100
1158
|
academic: "Academic",
|
|
1101
|
-
other: "
|
|
1159
|
+
other: "Independent sites"
|
|
1102
1160
|
};
|
|
1103
1161
|
function categorizeSource(uri) {
|
|
1104
1162
|
let domain;
|
|
@@ -1116,6 +1174,13 @@ function categorizeSource(uri) {
|
|
|
1116
1174
|
}
|
|
1117
1175
|
return { category: "other", label: CATEGORY_LABELS.other, domain };
|
|
1118
1176
|
}
|
|
1177
|
+
function categorizeSourceWithCompetitors(uri, competitorDomains, isCompetitorMatch) {
|
|
1178
|
+
const base = categorizeSource(uri);
|
|
1179
|
+
if (isCompetitorMatch(base.domain, competitorDomains)) {
|
|
1180
|
+
return { category: "competitor", label: CATEGORY_LABELS.competitor, domain: base.domain };
|
|
1181
|
+
}
|
|
1182
|
+
return base;
|
|
1183
|
+
}
|
|
1119
1184
|
function categoryLabel(category) {
|
|
1120
1185
|
return CATEGORY_LABELS[category];
|
|
1121
1186
|
}
|
|
@@ -1897,6 +1962,14 @@ function citationStateToCited(state) {
|
|
|
1897
1962
|
return state === "cited";
|
|
1898
1963
|
}
|
|
1899
1964
|
|
|
1965
|
+
// ../contracts/src/report.ts
|
|
1966
|
+
function reportActionTone(action) {
|
|
1967
|
+
if (action.horizon === "immediate") return "negative";
|
|
1968
|
+
if (action.confidence === "high") return "caution";
|
|
1969
|
+
if (action.confidence === "low") return "neutral";
|
|
1970
|
+
return "caution";
|
|
1971
|
+
}
|
|
1972
|
+
|
|
1900
1973
|
// ../contracts/src/skills.ts
|
|
1901
1974
|
import { z as z19 } from "zod";
|
|
1902
1975
|
var codingAgentSchema = z19.enum(["claude", "codex"]);
|
|
@@ -1911,6 +1984,7 @@ export {
|
|
|
1911
1984
|
isBrowserProvider,
|
|
1912
1985
|
resolveProviderInput,
|
|
1913
1986
|
locationContextSchema,
|
|
1987
|
+
getProviderLocationHandling,
|
|
1914
1988
|
notificationEventSchema,
|
|
1915
1989
|
notificationCreateRequestSchema,
|
|
1916
1990
|
findDuplicateLocationLabels,
|
|
@@ -1960,6 +2034,7 @@ export {
|
|
|
1960
2034
|
parseWindow,
|
|
1961
2035
|
windowCutoff,
|
|
1962
2036
|
categorizeSource,
|
|
2037
|
+
categorizeSourceWithCompetitors,
|
|
1963
2038
|
categoryLabel,
|
|
1964
2039
|
extractAnswerMentions,
|
|
1965
2040
|
determineAnswerMentioned,
|
|
@@ -1980,6 +2055,7 @@ export {
|
|
|
1980
2055
|
normalizeUrlPath,
|
|
1981
2056
|
emptyCitationVisibility,
|
|
1982
2057
|
citationStateToCited,
|
|
2058
|
+
reportActionTone,
|
|
1983
2059
|
CodingAgents,
|
|
1984
2060
|
skillsClientSchema,
|
|
1985
2061
|
SkillsClients
|
package/dist/cli.js
CHANGED
|
@@ -18,7 +18,7 @@ import {
|
|
|
18
18
|
setGoogleAuthConfig,
|
|
19
19
|
showFirstRunNotice,
|
|
20
20
|
trackEvent
|
|
21
|
-
} from "./chunk-
|
|
21
|
+
} from "./chunk-DVTPGC6O.js";
|
|
22
22
|
import {
|
|
23
23
|
CliError,
|
|
24
24
|
EXIT_SYSTEM_ERROR,
|
|
@@ -33,7 +33,7 @@ import {
|
|
|
33
33
|
saveConfig,
|
|
34
34
|
saveConfigPatch,
|
|
35
35
|
usageError
|
|
36
|
-
} from "./chunk-
|
|
36
|
+
} from "./chunk-VDEMEI64.js";
|
|
37
37
|
import {
|
|
38
38
|
apiKeys,
|
|
39
39
|
competitors,
|
|
@@ -45,7 +45,7 @@ import {
|
|
|
45
45
|
projects,
|
|
46
46
|
querySnapshots,
|
|
47
47
|
runs
|
|
48
|
-
} from "./chunk-
|
|
48
|
+
} from "./chunk-OOADR2Q5.js";
|
|
49
49
|
import {
|
|
50
50
|
CcReleaseSyncStatuses,
|
|
51
51
|
CheckScopes,
|
|
@@ -64,7 +64,7 @@ import {
|
|
|
64
64
|
providerQuotaPolicySchema,
|
|
65
65
|
resolveProviderInput,
|
|
66
66
|
skillsClientSchema
|
|
67
|
-
} from "./chunk-
|
|
67
|
+
} from "./chunk-XAW66QUX.js";
|
|
68
68
|
|
|
69
69
|
// src/cli.ts
|
|
70
70
|
import { pathToFileURL } from "url";
|
|
@@ -580,7 +580,7 @@ function readStoredGroundingSources(rawResponse) {
|
|
|
580
580
|
return result;
|
|
581
581
|
}
|
|
582
582
|
async function backfillInsightsCommand(project, opts) {
|
|
583
|
-
const { IntelligenceService } = await import("./intelligence-service-
|
|
583
|
+
const { IntelligenceService } = await import("./intelligence-service-ABHO5HHA.js");
|
|
584
584
|
const config = loadConfig();
|
|
585
585
|
const db = createClient(config.database);
|
|
586
586
|
migrate(db);
|
|
@@ -5457,19 +5457,20 @@ var PROJECT_CLI_COMMANDS = [
|
|
|
5457
5457
|
// src/commands/report.ts
|
|
5458
5458
|
import fs5 from "fs";
|
|
5459
5459
|
import path3 from "path";
|
|
5460
|
-
function defaultOutputPath(project) {
|
|
5460
|
+
function defaultOutputPath(project, audience) {
|
|
5461
5461
|
const date = (/* @__PURE__ */ new Date()).toISOString().slice(0, 10);
|
|
5462
|
-
return path3.resolve(process.cwd(), `canonry-report-${project}-${date}.html`);
|
|
5462
|
+
return path3.resolve(process.cwd(), `canonry-report-${project}-${audience}-${date}.html`);
|
|
5463
5463
|
}
|
|
5464
5464
|
async function runReportCommand(project, opts = {}) {
|
|
5465
5465
|
const client = createApiClient();
|
|
5466
5466
|
const report = await client.getReport(project);
|
|
5467
|
+
const audience = opts.audience ?? "agency";
|
|
5467
5468
|
if (opts.format === "json") {
|
|
5468
5469
|
console.log(JSON.stringify(report, null, 2));
|
|
5469
5470
|
return;
|
|
5470
5471
|
}
|
|
5471
|
-
const html = renderReportHtml(report);
|
|
5472
|
-
const targetPath = opts.output ? path3.resolve(opts.output) : defaultOutputPath(project);
|
|
5472
|
+
const html = renderReportHtml(report, { audience });
|
|
5473
|
+
const targetPath = opts.output ? path3.resolve(opts.output) : defaultOutputPath(project, audience);
|
|
5473
5474
|
const dir = path3.dirname(targetPath);
|
|
5474
5475
|
if (!fs5.existsSync(dir)) {
|
|
5475
5476
|
fs5.mkdirSync(dir, { recursive: true });
|
|
@@ -5479,18 +5480,27 @@ async function runReportCommand(project, opts = {}) {
|
|
|
5479
5480
|
}
|
|
5480
5481
|
|
|
5481
5482
|
// src/cli-commands/report.ts
|
|
5482
|
-
var USAGE2 = "canonry report <project> [--output <path>] [--format json]";
|
|
5483
|
+
var USAGE2 = "canonry report <project> [--audience agency|client] [--output <path>] [--format json]";
|
|
5484
|
+
function parseAudience(value) {
|
|
5485
|
+
if (value === void 0) return void 0;
|
|
5486
|
+
if (value === "agency" || value === "client") return value;
|
|
5487
|
+
throw usageError(`Error: --audience must be "agency" or "client"
|
|
5488
|
+
|
|
5489
|
+
Usage: ${USAGE2}`);
|
|
5490
|
+
}
|
|
5483
5491
|
var REPORT_CLI_COMMANDS = [
|
|
5484
5492
|
{
|
|
5485
5493
|
path: ["report"],
|
|
5486
5494
|
usage: USAGE2,
|
|
5487
5495
|
options: {
|
|
5496
|
+
audience: { type: "string" },
|
|
5488
5497
|
output: { type: "string", short: "o" }
|
|
5489
5498
|
},
|
|
5490
5499
|
run: async (input) => {
|
|
5491
5500
|
const project = requireProject(input, "report", USAGE2);
|
|
5492
5501
|
await runReportCommand(project, {
|
|
5493
5502
|
format: input.format,
|
|
5503
|
+
audience: parseAudience(getString(input.values, "audience")),
|
|
5494
5504
|
output: getString(input.values, "output")
|
|
5495
5505
|
});
|
|
5496
5506
|
}
|
package/dist/index.js
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import {
|
|
2
2
|
createServer
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-DVTPGC6O.js";
|
|
4
4
|
import {
|
|
5
5
|
loadConfig
|
|
6
|
-
} from "./chunk-
|
|
7
|
-
import "./chunk-
|
|
8
|
-
import "./chunk-
|
|
6
|
+
} from "./chunk-VDEMEI64.js";
|
|
7
|
+
import "./chunk-OOADR2Q5.js";
|
|
8
|
+
import "./chunk-XAW66QUX.js";
|
|
9
9
|
export {
|
|
10
10
|
createServer,
|
|
11
11
|
loadConfig
|
package/dist/mcp.js
CHANGED
|
@@ -2,8 +2,8 @@ import {
|
|
|
2
2
|
CliError,
|
|
3
3
|
canonryMcpTools,
|
|
4
4
|
createApiClient
|
|
5
|
-
} from "./chunk-
|
|
6
|
-
import "./chunk-
|
|
5
|
+
} from "./chunk-VDEMEI64.js";
|
|
6
|
+
import "./chunk-XAW66QUX.js";
|
|
7
7
|
|
|
8
8
|
// src/mcp/cli.ts
|
|
9
9
|
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.7.2",
|
|
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",
|
|
@@ -59,20 +59,20 @@
|
|
|
59
59
|
"@types/node-cron": "^3.0.11",
|
|
60
60
|
"tsup": "^8.5.1",
|
|
61
61
|
"tsx": "^4.19.0",
|
|
62
|
-
"@ainyc/canonry-api-routes": "0.0.0",
|
|
63
62
|
"@ainyc/canonry-contracts": "0.0.0",
|
|
64
|
-
"@ainyc/canonry-
|
|
63
|
+
"@ainyc/canonry-api-routes": "0.0.0",
|
|
65
64
|
"@ainyc/canonry-intelligence": "0.0.0",
|
|
66
|
-
"@ainyc/canonry-config": "0.0.0",
|
|
67
|
-
"@ainyc/canonry-integration-commoncrawl": "0.0.0",
|
|
68
65
|
"@ainyc/canonry-integration-bing": "0.0.0",
|
|
66
|
+
"@ainyc/canonry-db": "0.0.0",
|
|
67
|
+
"@ainyc/canonry-integration-commoncrawl": "0.0.0",
|
|
68
|
+
"@ainyc/canonry-integration-google": "0.0.0",
|
|
69
|
+
"@ainyc/canonry-config": "0.0.0",
|
|
69
70
|
"@ainyc/canonry-integration-wordpress": "0.0.0",
|
|
71
|
+
"@ainyc/canonry-provider-cdp": "0.0.0",
|
|
70
72
|
"@ainyc/canonry-provider-claude": "0.0.0",
|
|
73
|
+
"@ainyc/canonry-provider-local": "0.0.0",
|
|
71
74
|
"@ainyc/canonry-provider-gemini": "0.0.0",
|
|
72
|
-
"@ainyc/canonry-provider-cdp": "0.0.0",
|
|
73
|
-
"@ainyc/canonry-integration-google": "0.0.0",
|
|
74
75
|
"@ainyc/canonry-provider-openai": "0.0.0",
|
|
75
|
-
"@ainyc/canonry-provider-local": "0.0.0",
|
|
76
76
|
"@ainyc/canonry-provider-perplexity": "0.0.0"
|
|
77
77
|
},
|
|
78
78
|
"scripts": {
|