@ainyc/canonry 4.1.3 → 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-JV6X6AFT.js → chunk-DVTPGC6O.js} +1087 -348
- package/dist/{chunk-AXMSAMKN.js → chunk-OOADR2Q5.js} +764 -26
- package/dist/{chunk-KCETXLDF.js → chunk-VDEMEI64.js} +19 -7
- package/dist/{chunk-O5JZQUPX.js → chunk-XAW66QUX.js} +87 -2
- package/dist/cli.js +102 -23
- package/dist/index.js +4 -4
- package/dist/{intelligence-service-WPY4PDBU.js → intelligence-service-ABHO5HHA.js} +2 -2
- package/dist/mcp.js +2 -2
- package/package.json +7 -7
- package/assets/assets/index-BbhhYPML.js +0 -302
|
@@ -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";
|
|
@@ -864,8 +864,13 @@ var ApiClient = class {
|
|
|
864
864
|
async getHealth(project) {
|
|
865
865
|
return this.request("GET", `/projects/${encodeURIComponent(project)}/health/latest`);
|
|
866
866
|
}
|
|
867
|
-
async getProjectOverview(project) {
|
|
868
|
-
|
|
867
|
+
async getProjectOverview(project, opts) {
|
|
868
|
+
const params = new URLSearchParams();
|
|
869
|
+
if (opts?.location) params.set("location", opts.location);
|
|
870
|
+
if (opts?.since) params.set("since", opts.since);
|
|
871
|
+
const query = params.toString();
|
|
872
|
+
const path2 = `/projects/${encodeURIComponent(project)}/overview${query ? `?${query}` : ""}`;
|
|
873
|
+
return this.request("GET", path2);
|
|
869
874
|
}
|
|
870
875
|
async searchProject(project, opts) {
|
|
871
876
|
const params = new URLSearchParams({ q: opts.q });
|
|
@@ -1153,18 +1158,25 @@ var canonryMcpTools = [
|
|
|
1153
1158
|
defineTool({
|
|
1154
1159
|
name: "canonry_project_overview",
|
|
1155
1160
|
title: "Get project overview (composite)",
|
|
1156
|
-
description: 'One-call summary for "how is project X doing?" \u2014 bundles project info, latest run, top undismissed insights, latest health snapshot, query cited rate, per-provider breakdown,
|
|
1161
|
+
description: 'One-call summary for "how is project X doing?" \u2014 bundles project info, latest run, top undismissed insights, latest health snapshot, query cited rate, per-provider breakdown, gained/lost/emerging vs the previous run, the five score gauges (visibility, gap queries, index coverage, competitor pressure, run status), per-(provider, model) scores, configured competitors with pressure labels, an attention queue of critical/high insights, and a recent-runs sparkline. Filterable by location and time window. Prefer this over fanning out to separate tools.',
|
|
1157
1162
|
access: "read",
|
|
1158
1163
|
tier: "core",
|
|
1159
|
-
inputSchema:
|
|
1164
|
+
inputSchema: z2.object({
|
|
1165
|
+
project: projectNameSchema,
|
|
1166
|
+
location: z2.string().optional().describe('Filter to runs from this location label (e.g. "Boston, MA, US"). Omit for all locations.'),
|
|
1167
|
+
since: z2.string().optional().describe("ISO 8601 datetime \u2014 only include runs at or after this time. Omit for full history.")
|
|
1168
|
+
}),
|
|
1160
1169
|
annotations: readAnnotations(),
|
|
1161
1170
|
openApiOperations: ["GET /api/v1/projects/{name}/overview"],
|
|
1162
|
-
handler: (client, input) => client.getProjectOverview(input.project
|
|
1171
|
+
handler: (client, input) => client.getProjectOverview(input.project, {
|
|
1172
|
+
location: input.location,
|
|
1173
|
+
since: input.since
|
|
1174
|
+
})
|
|
1163
1175
|
}),
|
|
1164
1176
|
defineTool({
|
|
1165
1177
|
name: "canonry_report",
|
|
1166
1178
|
title: "Get aggregated AEO report",
|
|
1167
|
-
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.",
|
|
1168
1180
|
access: "read",
|
|
1169
1181
|
tier: "monitoring",
|
|
1170
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
|
}
|
|
@@ -1509,7 +1574,16 @@ var projectSearchInsightHitSchema = z15.object({
|
|
|
1509
1574
|
kind: z15.literal("insight"),
|
|
1510
1575
|
id: z15.string(),
|
|
1511
1576
|
runId: z15.string().nullable(),
|
|
1512
|
-
type: z15.enum([
|
|
1577
|
+
type: z15.enum([
|
|
1578
|
+
"regression",
|
|
1579
|
+
"gain",
|
|
1580
|
+
"opportunity",
|
|
1581
|
+
"first-citation",
|
|
1582
|
+
"provider-pickup",
|
|
1583
|
+
"persistent-gap",
|
|
1584
|
+
"competitor-gained",
|
|
1585
|
+
"competitor-lost"
|
|
1586
|
+
]),
|
|
1513
1587
|
severity: z15.enum(["critical", "high", "medium", "low"]),
|
|
1514
1588
|
title: z15.string(),
|
|
1515
1589
|
query: z15.string(),
|
|
@@ -1888,6 +1962,14 @@ function citationStateToCited(state) {
|
|
|
1888
1962
|
return state === "cited";
|
|
1889
1963
|
}
|
|
1890
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
|
+
|
|
1891
1973
|
// ../contracts/src/skills.ts
|
|
1892
1974
|
import { z as z19 } from "zod";
|
|
1893
1975
|
var codingAgentSchema = z19.enum(["claude", "codex"]);
|
|
@@ -1902,6 +1984,7 @@ export {
|
|
|
1902
1984
|
isBrowserProvider,
|
|
1903
1985
|
resolveProviderInput,
|
|
1904
1986
|
locationContextSchema,
|
|
1987
|
+
getProviderLocationHandling,
|
|
1905
1988
|
notificationEventSchema,
|
|
1906
1989
|
notificationCreateRequestSchema,
|
|
1907
1990
|
findDuplicateLocationLabels,
|
|
@@ -1951,6 +2034,7 @@ export {
|
|
|
1951
2034
|
parseWindow,
|
|
1952
2035
|
windowCutoff,
|
|
1953
2036
|
categorizeSource,
|
|
2037
|
+
categorizeSourceWithCompetitors,
|
|
1954
2038
|
categoryLabel,
|
|
1955
2039
|
extractAnswerMentions,
|
|
1956
2040
|
determineAnswerMentioned,
|
|
@@ -1971,6 +2055,7 @@ export {
|
|
|
1971
2055
|
normalizeUrlPath,
|
|
1972
2056
|
emptyCitationVisibility,
|
|
1973
2057
|
citationStateToCited,
|
|
2058
|
+
reportActionTone,
|
|
1974
2059
|
CodingAgents,
|
|
1975
2060
|
skillsClientSchema,
|
|
1976
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
|
}
|
|
@@ -7142,17 +7152,37 @@ async function showHealth(project, opts) {
|
|
|
7142
7152
|
// src/commands/overview.ts
|
|
7143
7153
|
async function showOverview(project, opts) {
|
|
7144
7154
|
const client = createApiClient();
|
|
7145
|
-
const overview = await client.getProjectOverview(project
|
|
7155
|
+
const overview = await client.getProjectOverview(project, {
|
|
7156
|
+
location: opts.location,
|
|
7157
|
+
since: opts.since
|
|
7158
|
+
});
|
|
7146
7159
|
if (opts.format === "json") {
|
|
7147
7160
|
console.log(JSON.stringify(overview, null, 2));
|
|
7148
7161
|
return;
|
|
7149
7162
|
}
|
|
7150
|
-
|
|
7151
|
-
|
|
7152
|
-
|
|
7163
|
+
renderHuman(overview);
|
|
7164
|
+
}
|
|
7165
|
+
function renderHuman(overview) {
|
|
7166
|
+
const {
|
|
7167
|
+
project: meta,
|
|
7168
|
+
latestRun,
|
|
7169
|
+
health,
|
|
7170
|
+
topInsights,
|
|
7171
|
+
queryCounts,
|
|
7172
|
+
providers,
|
|
7173
|
+
transitions,
|
|
7174
|
+
scores,
|
|
7175
|
+
movementSummary,
|
|
7176
|
+
competitors: competitors2,
|
|
7177
|
+
providerScores,
|
|
7178
|
+
attentionItems,
|
|
7179
|
+
runHistory,
|
|
7180
|
+
dateRangeLabel,
|
|
7181
|
+
contextLabel
|
|
7182
|
+
} = overview;
|
|
7183
|
+
console.log(`Overview: ${meta.displayName ?? meta.name} (${meta.name})`);
|
|
7153
7184
|
console.log(` Domain: ${meta.canonicalDomain}`);
|
|
7154
|
-
console.log(`
|
|
7155
|
-
console.log(` Language: ${meta.language}`);
|
|
7185
|
+
console.log(` Context: ${contextLabel} \xB7 ${dateRangeLabel}`);
|
|
7156
7186
|
if (latestRun.run) {
|
|
7157
7187
|
const finished = latestRun.run.finishedAt ?? "\u2014";
|
|
7158
7188
|
console.log(`
|
|
@@ -7161,17 +7191,48 @@ async function showOverview(project, opts) {
|
|
|
7161
7191
|
} else {
|
|
7162
7192
|
console.log("\n No runs yet.");
|
|
7163
7193
|
}
|
|
7194
|
+
console.log("\nScores:");
|
|
7195
|
+
printScore("Visibility ", scores.visibility);
|
|
7196
|
+
printScore("Gap queries ", scores.gapQueries);
|
|
7197
|
+
printScore("Index coverage ", scores.indexCoverage);
|
|
7198
|
+
printScore("Competitor press.", scores.competitorPressure);
|
|
7199
|
+
printScore("Run status ", scores.runStatus);
|
|
7164
7200
|
console.log(`
|
|
7165
7201
|
Queries cited: ${queryCounts.citedQueries}/${queryCounts.totalQueries} (${pct(queryCounts.citedRate)})`);
|
|
7202
|
+
if (movementSummary.hasPreviousRun) {
|
|
7203
|
+
console.log(` Movement: +${movementSummary.gained} gained, -${movementSummary.lost} lost (${movementSummary.tone})`);
|
|
7204
|
+
} else if (movementSummary.gained > 0) {
|
|
7205
|
+
console.log(` Movement: ${movementSummary.gained} cited in first run`);
|
|
7206
|
+
}
|
|
7166
7207
|
if (providers.length > 0) {
|
|
7167
|
-
console.log(" Providers:");
|
|
7208
|
+
console.log("\n Providers:");
|
|
7168
7209
|
for (const p of providers) {
|
|
7169
|
-
console.log(` ${p.provider.padEnd(
|
|
7210
|
+
console.log(` ${p.provider.padEnd(12)} ${p.cited}/${p.total} (${pct(p.citedRate)})`);
|
|
7211
|
+
}
|
|
7212
|
+
}
|
|
7213
|
+
if (providerScores.length > 0) {
|
|
7214
|
+
console.log("\n Models:");
|
|
7215
|
+
for (const m of providerScores) {
|
|
7216
|
+
const label = `${m.provider}/${m.model ?? "unknown"}`.padEnd(28);
|
|
7217
|
+
console.log(` ${label} ${m.cited}/${m.total} (${m.score}%)`);
|
|
7170
7218
|
}
|
|
7171
7219
|
}
|
|
7172
7220
|
if (transitions.since) {
|
|
7173
7221
|
console.log(`
|
|
7174
|
-
|
|
7222
|
+
Transitions since ${transitions.since}: +${transitions.gained} gained, -${transitions.lost} lost, ${transitions.emerging} emerging`);
|
|
7223
|
+
}
|
|
7224
|
+
if (competitors2.length > 0) {
|
|
7225
|
+
console.log("\n Competitors:");
|
|
7226
|
+
for (const c of competitors2) {
|
|
7227
|
+
console.log(` ${c.domain.padEnd(28)} ${c.citationCount}/${c.totalQueries} ${c.pressureLabel}`);
|
|
7228
|
+
}
|
|
7229
|
+
}
|
|
7230
|
+
if (attentionItems.length > 0) {
|
|
7231
|
+
console.log("\n Attention:");
|
|
7232
|
+
for (const item of attentionItems) {
|
|
7233
|
+
console.log(` [${item.actionLabel}] ${item.title}`);
|
|
7234
|
+
if (item.detail) console.log(` ${item.detail}`);
|
|
7235
|
+
}
|
|
7175
7236
|
}
|
|
7176
7237
|
if (health) {
|
|
7177
7238
|
console.log(`
|
|
@@ -7183,6 +7244,19 @@ async function showOverview(project, opts) {
|
|
|
7183
7244
|
console.log(` [${insight.severity.toUpperCase()}] ${insight.type} \u2014 ${insight.title}`);
|
|
7184
7245
|
}
|
|
7185
7246
|
}
|
|
7247
|
+
if (runHistory.length > 0) {
|
|
7248
|
+
console.log(`
|
|
7249
|
+
Run history (last ${runHistory.length}):`);
|
|
7250
|
+
for (const point of runHistory) {
|
|
7251
|
+
const bar = "\u2588".repeat(Math.round(point.citationRate / 10));
|
|
7252
|
+
console.log(` ${point.createdAt.slice(0, 10)} ${String(point.citationRate).padStart(3)}% ${bar}`);
|
|
7253
|
+
}
|
|
7254
|
+
}
|
|
7255
|
+
}
|
|
7256
|
+
function printScore(prefix, score) {
|
|
7257
|
+
const tone = `[${score.tone}]`.padEnd(11);
|
|
7258
|
+
const value = score.value.padEnd(8);
|
|
7259
|
+
console.log(` ${prefix} ${tone} ${value} ${score.delta}`);
|
|
7186
7260
|
}
|
|
7187
7261
|
function pct(value) {
|
|
7188
7262
|
return `${(value * 100).toFixed(1)}%`;
|
|
@@ -7361,12 +7435,17 @@ var INTELLIGENCE_CLI_COMMANDS = [
|
|
|
7361
7435
|
},
|
|
7362
7436
|
{
|
|
7363
7437
|
path: ["overview"],
|
|
7364
|
-
usage: "canonry overview <project> [--format json]",
|
|
7365
|
-
options: {
|
|
7438
|
+
usage: "canonry overview <project> [--location <label>] [--since <iso>] [--format json]",
|
|
7439
|
+
options: {
|
|
7440
|
+
location: { type: "string" },
|
|
7441
|
+
since: { type: "string" }
|
|
7442
|
+
},
|
|
7366
7443
|
run: async (input) => {
|
|
7367
|
-
const usage = "canonry overview <project> [--format json]";
|
|
7444
|
+
const usage = "canonry overview <project> [--location <label>] [--since <iso>] [--format json]";
|
|
7368
7445
|
const project = requireProject(input, "overview", usage);
|
|
7369
|
-
|
|
7446
|
+
const location = getString(input.values, "location");
|
|
7447
|
+
const since = getString(input.values, "since");
|
|
7448
|
+
await showOverview(project, { format: input.format, location, since });
|
|
7370
7449
|
}
|
|
7371
7450
|
},
|
|
7372
7451
|
{
|
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,19 +59,19 @@
|
|
|
59
59
|
"@types/node-cron": "^3.0.11",
|
|
60
60
|
"tsup": "^8.5.1",
|
|
61
61
|
"tsx": "^4.19.0",
|
|
62
|
+
"@ainyc/canonry-contracts": "0.0.0",
|
|
62
63
|
"@ainyc/canonry-api-routes": "0.0.0",
|
|
63
|
-
"@ainyc/canonry-config": "0.0.0",
|
|
64
|
-
"@ainyc/canonry-db": "0.0.0",
|
|
65
|
-
"@ainyc/canonry-integration-bing": "0.0.0",
|
|
66
64
|
"@ainyc/canonry-intelligence": "0.0.0",
|
|
67
|
-
"@ainyc/canonry-
|
|
65
|
+
"@ainyc/canonry-integration-bing": "0.0.0",
|
|
66
|
+
"@ainyc/canonry-db": "0.0.0",
|
|
68
67
|
"@ainyc/canonry-integration-commoncrawl": "0.0.0",
|
|
69
68
|
"@ainyc/canonry-integration-google": "0.0.0",
|
|
69
|
+
"@ainyc/canonry-config": "0.0.0",
|
|
70
|
+
"@ainyc/canonry-integration-wordpress": "0.0.0",
|
|
70
71
|
"@ainyc/canonry-provider-cdp": "0.0.0",
|
|
71
72
|
"@ainyc/canonry-provider-claude": "0.0.0",
|
|
72
|
-
"@ainyc/canonry-integration-wordpress": "0.0.0",
|
|
73
|
-
"@ainyc/canonry-provider-gemini": "0.0.0",
|
|
74
73
|
"@ainyc/canonry-provider-local": "0.0.0",
|
|
74
|
+
"@ainyc/canonry-provider-gemini": "0.0.0",
|
|
75
75
|
"@ainyc/canonry-provider-openai": "0.0.0",
|
|
76
76
|
"@ainyc/canonry-provider-perplexity": "0.0.0"
|
|
77
77
|
},
|