@ainyc/canonry 4.115.1 → 4.117.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/README.md +0 -1
- package/assets/agent-workspace/skills/aero/references/reporting.md +10 -0
- package/assets/agent-workspace/skills/canonry/references/canonry-cli.md +6 -0
- package/assets/assets/{BacklinksPage-yUb8oJuq.js → BacklinksPage-Bkafm10m.js} +1 -1
- package/assets/assets/{ChartPrimitives-CdQM3YDG.js → ChartPrimitives-NV_GgqFn.js} +1 -1
- package/assets/assets/ProjectPage-0-NnRxys.js +7 -0
- package/assets/assets/{RunRow-BU_x7EcP.js → RunRow-df0d24S6.js} +1 -1
- package/assets/assets/{RunsPage-CFIBWaO7.js → RunsPage-CU6-4YTM.js} +1 -1
- package/assets/assets/{SettingsPage-PyMryUad.js → SettingsPage-BKw6B6cd.js} +1 -1
- package/assets/assets/{TrafficPage-471ypAdQ.js → TrafficPage-CzpiYHKj.js} +1 -1
- package/assets/assets/{TrafficSourceDetailPage-CI7TEQge.js → TrafficSourceDetailPage-CC5nuqM1.js} +1 -1
- package/assets/assets/{arrow-left-D2N9u-0i.js → arrow-left-CbQcW2pL.js} +1 -1
- package/assets/assets/{extract-error-message-CAdsqKp3.js → extract-error-message-CvqIZ-le.js} +1 -1
- package/assets/assets/index-LjcWHaNZ.js +210 -0
- package/assets/assets/{trash-2-UgQrN5Np.js → trash-2-3J2u0woR.js} +1 -1
- package/assets/index.html +1 -1
- package/dist/{chunk-Z3OGDQHB.js → chunk-FVVKNMZW.js} +514 -52
- package/dist/{chunk-6LOKMEL3.js → chunk-IAJ5TQ4S.js} +1438 -1234
- package/dist/{chunk-CW4JISBL.js → chunk-PJATAPZW.js} +37 -1
- package/dist/{chunk-B2SNXXAJ.js → chunk-ZZEA774R.js} +4 -4
- package/dist/cli.js +98 -5
- package/dist/index.js +4 -4
- package/dist/{intelligence-service-4AWB2V7U.js → intelligence-service-J7G4CMI5.js} +2 -2
- package/dist/mcp.js +2 -2
- package/package.json +6 -6
- package/assets/assets/ProjectPage-CHj9fvTs.js +0 -7
- package/assets/assets/index-CoL5HENE.js +0 -210
|
@@ -25,7 +25,7 @@ import {
|
|
|
25
25
|
trafficConnectVercelRequestSchema,
|
|
26
26
|
trafficConnectWordpressRequestSchema,
|
|
27
27
|
trafficEventKindSchema
|
|
28
|
-
} from "./chunk-
|
|
28
|
+
} from "./chunk-IAJ5TQ4S.js";
|
|
29
29
|
|
|
30
30
|
// src/config.ts
|
|
31
31
|
import fs from "fs";
|
|
@@ -1578,6 +1578,18 @@ var getApiV1ProjectsByNameVisibilityStats = (options) => {
|
|
|
1578
1578
|
...options
|
|
1579
1579
|
});
|
|
1580
1580
|
};
|
|
1581
|
+
var getApiV1ProjectsByNameVisibilityCompare = (options) => {
|
|
1582
|
+
return (options.client ?? client).get({
|
|
1583
|
+
security: [
|
|
1584
|
+
{
|
|
1585
|
+
scheme: "bearer",
|
|
1586
|
+
type: "http"
|
|
1587
|
+
}
|
|
1588
|
+
],
|
|
1589
|
+
url: "/api/v1/projects/{name}/visibility-compare",
|
|
1590
|
+
...options
|
|
1591
|
+
});
|
|
1592
|
+
};
|
|
1581
1593
|
var getApiV1ProjectsByNameSnapshotsDiff = (options) => {
|
|
1582
1594
|
return (options.client ?? client).get({
|
|
1583
1595
|
security: [
|
|
@@ -5171,6 +5183,15 @@ var ApiClient = class {
|
|
|
5171
5183
|
})
|
|
5172
5184
|
);
|
|
5173
5185
|
}
|
|
5186
|
+
async getVisibilityCompare(project, from, to) {
|
|
5187
|
+
return this.invoke(
|
|
5188
|
+
() => getApiV1ProjectsByNameVisibilityCompare({
|
|
5189
|
+
client: this.heyClient,
|
|
5190
|
+
path: { name: project },
|
|
5191
|
+
query: { from, to }
|
|
5192
|
+
})
|
|
5193
|
+
);
|
|
5194
|
+
}
|
|
5174
5195
|
// ── Backlinks — workspace-level ────────────────────────────────────────
|
|
5175
5196
|
async backlinksStatus() {
|
|
5176
5197
|
return this.invoke(() => getApiV1BacklinksStatus({ client: this.heyClient }));
|
|
@@ -5915,6 +5936,21 @@ var canonryMcpTools = [
|
|
|
5915
5936
|
shareOfVoice: input.shareOfVoice
|
|
5916
5937
|
})
|
|
5917
5938
|
}),
|
|
5939
|
+
defineTool({
|
|
5940
|
+
name: "canonry_visibility_compare",
|
|
5941
|
+
title: "Compare AEO visibility month over month",
|
|
5942
|
+
description: "Statistically honest month-over-month AEO comparison in ONE call \u2014 use this instead of hand-computing deltas from two visibility-stats calls. Share of voice (`mention-share-of-voice`, `driftRobust: true`) is less exposed to broad model-wide naming propensity than absolute rates, but it never overrides model continuity. The response restricts to common query/provider pairs, then includes only providers with exactly one known, identical configured model id in both months. `continuity` surfaces every provider, its model evidence, and whether it was excluded for a changed, mixed mid-month, or unknown model. When no provider remains, metrics return `model-discontinuous` or `model-unknown`, never a directional call. A silent upstream version bump under an unchanged configured id remains undetectable. `from` must be a month strictly before `to`.",
|
|
5943
|
+
access: "read",
|
|
5944
|
+
tier: "monitoring",
|
|
5945
|
+
inputSchema: z2.object({
|
|
5946
|
+
project: projectNameSchema,
|
|
5947
|
+
from: z2.string().describe('Earlier calendar month (YYYY-MM), the baseline. Must be strictly before "to".'),
|
|
5948
|
+
to: z2.string().describe('Later calendar month (YYYY-MM), compared against "from".')
|
|
5949
|
+
}),
|
|
5950
|
+
annotations: readAnnotations(),
|
|
5951
|
+
openApiOperations: ["GET /api/v1/projects/{name}/visibility-compare"],
|
|
5952
|
+
handler: (client2, input) => client2.getVisibilityCompare(input.project, input.from, input.to)
|
|
5953
|
+
}),
|
|
5918
5954
|
defineTool({
|
|
5919
5955
|
name: "canonry_content_targets",
|
|
5920
5956
|
title: "Get content targets",
|
|
@@ -10,7 +10,7 @@ import {
|
|
|
10
10
|
loadConfig,
|
|
11
11
|
loadConfigRaw,
|
|
12
12
|
saveConfigPatch
|
|
13
|
-
} from "./chunk-
|
|
13
|
+
} from "./chunk-PJATAPZW.js";
|
|
14
14
|
import {
|
|
15
15
|
CC_CACHE_DIR,
|
|
16
16
|
DUCKDB_SPEC,
|
|
@@ -115,7 +115,7 @@ import {
|
|
|
115
115
|
siteAuditPages,
|
|
116
116
|
siteAuditSnapshots,
|
|
117
117
|
usageCounters
|
|
118
|
-
} from "./chunk-
|
|
118
|
+
} from "./chunk-FVVKNMZW.js";
|
|
119
119
|
import {
|
|
120
120
|
AGENT_MEMORY_VALUE_MAX_BYTES,
|
|
121
121
|
AGENT_PROVIDER_IDS,
|
|
@@ -178,7 +178,7 @@ import {
|
|
|
178
178
|
validationError,
|
|
179
179
|
winnabilityClassLabel,
|
|
180
180
|
withRetry
|
|
181
|
-
} from "./chunk-
|
|
181
|
+
} from "./chunk-IAJ5TQ4S.js";
|
|
182
182
|
|
|
183
183
|
// src/telemetry.ts
|
|
184
184
|
import crypto from "crypto";
|
|
@@ -6515,7 +6515,7 @@ function readStoredGroundingSources(rawResponse) {
|
|
|
6515
6515
|
return result;
|
|
6516
6516
|
}
|
|
6517
6517
|
async function backfillInsightsCommand(project, opts) {
|
|
6518
|
-
const { IntelligenceService: IntelligenceService2 } = await import("./intelligence-service-
|
|
6518
|
+
const { IntelligenceService: IntelligenceService2 } = await import("./intelligence-service-J7G4CMI5.js");
|
|
6519
6519
|
const config = loadConfig();
|
|
6520
6520
|
const db = createClient(config.database);
|
|
6521
6521
|
migrate(db);
|
package/dist/cli.js
CHANGED
|
@@ -29,7 +29,7 @@ import {
|
|
|
29
29
|
setTelemetrySource,
|
|
30
30
|
showFirstRunNotice,
|
|
31
31
|
trackEvent
|
|
32
|
-
} from "./chunk-
|
|
32
|
+
} from "./chunk-ZZEA774R.js";
|
|
33
33
|
import {
|
|
34
34
|
CliError,
|
|
35
35
|
EXIT_SYSTEM_ERROR,
|
|
@@ -46,7 +46,7 @@ import {
|
|
|
46
46
|
saveConfig,
|
|
47
47
|
saveConfigPatch,
|
|
48
48
|
usageError
|
|
49
|
-
} from "./chunk-
|
|
49
|
+
} from "./chunk-PJATAPZW.js";
|
|
50
50
|
import {
|
|
51
51
|
apiKeys,
|
|
52
52
|
createClient,
|
|
@@ -54,7 +54,7 @@ import {
|
|
|
54
54
|
projects,
|
|
55
55
|
queries,
|
|
56
56
|
renderReportHtml
|
|
57
|
-
} from "./chunk-
|
|
57
|
+
} from "./chunk-FVVKNMZW.js";
|
|
58
58
|
import {
|
|
59
59
|
BacklinkSources,
|
|
60
60
|
CcReleaseSyncStatuses,
|
|
@@ -80,7 +80,7 @@ import {
|
|
|
80
80
|
providerQuotaPolicySchema,
|
|
81
81
|
resolveProviderInput,
|
|
82
82
|
winnabilityClassSchema
|
|
83
|
-
} from "./chunk-
|
|
83
|
+
} from "./chunk-IAJ5TQ4S.js";
|
|
84
84
|
|
|
85
85
|
// src/cli.ts
|
|
86
86
|
import { pathToFileURL } from "url";
|
|
@@ -4698,7 +4698,8 @@ function formatEventLine(event) {
|
|
|
4698
4698
|
event.evidenceType,
|
|
4699
4699
|
event.sourceDomain,
|
|
4700
4700
|
event.landingPathNormalized,
|
|
4701
|
-
`${event.hits} hits
|
|
4701
|
+
`${event.hits} hits`,
|
|
4702
|
+
`(paid ${event.paidHits} \xB7 organic ${event.organicHits} \xB7 unclassified ${event.unknownHits})`
|
|
4702
4703
|
].join(" ");
|
|
4703
4704
|
}
|
|
4704
4705
|
}
|
|
@@ -4743,6 +4744,9 @@ async function trafficEvents(project, opts) {
|
|
|
4743
4744
|
console.log(` Crawler hits total (window): ${result.totals.crawlerHits}`);
|
|
4744
4745
|
console.log(` AI user-fetch hits (window): ${result.totals.aiUserFetchHits}`);
|
|
4745
4746
|
console.log(` AI referral sessions (window): ${result.totals.aiReferralHits}`);
|
|
4747
|
+
console.log(` paid: ${result.totals.aiReferralPaidHits}`);
|
|
4748
|
+
console.log(` organic: ${result.totals.aiReferralOrganicHits}`);
|
|
4749
|
+
console.log(` unclassified: ${result.totals.aiReferralUnknownHits} (ingested before paid/organic classification)`);
|
|
4746
4750
|
console.log("");
|
|
4747
4751
|
if (result.events.length === 0) {
|
|
4748
4752
|
console.log("No events in this window.");
|
|
@@ -11837,6 +11841,78 @@ async function showVisibilityStats(project, opts) {
|
|
|
11837
11841
|
function pct3(rate) {
|
|
11838
11842
|
return rate === null ? "\u2014" : formatRatio(rate);
|
|
11839
11843
|
}
|
|
11844
|
+
async function showVisibilityCompare(project, opts) {
|
|
11845
|
+
if (!opts.from || !opts.to) throw new Error("visibility-compare requires --from <YYYY-MM> and --to <YYYY-MM>");
|
|
11846
|
+
const client = createApiClient();
|
|
11847
|
+
const data = await client.getVisibilityCompare(project, opts.from, opts.to);
|
|
11848
|
+
if (isMachineFormat(opts.format)) {
|
|
11849
|
+
console.log(JSON.stringify(data, null, 2));
|
|
11850
|
+
return;
|
|
11851
|
+
}
|
|
11852
|
+
printVisibilityCompare(data);
|
|
11853
|
+
}
|
|
11854
|
+
function periodCell(p) {
|
|
11855
|
+
if (p.point === null || p.ciLow === null || p.ciHigh === null) return "no data";
|
|
11856
|
+
const p1 = (v) => formatRatio(v);
|
|
11857
|
+
return `${p1(p.point)} [${p1(p.ciLow)}, ${p1(p.ciHigh)}]`;
|
|
11858
|
+
}
|
|
11859
|
+
function verdictCell(m) {
|
|
11860
|
+
switch (m.verdict) {
|
|
11861
|
+
case "within-noise":
|
|
11862
|
+
return "within noise";
|
|
11863
|
+
case "insufficient-data":
|
|
11864
|
+
return "no data";
|
|
11865
|
+
case "moved":
|
|
11866
|
+
return `moved ${m.direction === "down" ? "down" : m.direction === "up" ? "up" : ""}`.trim();
|
|
11867
|
+
case "model-discontinuous":
|
|
11868
|
+
return "model discontinuity";
|
|
11869
|
+
case "model-unknown":
|
|
11870
|
+
return "model unknown";
|
|
11871
|
+
}
|
|
11872
|
+
}
|
|
11873
|
+
function printVisibilityCompare(data) {
|
|
11874
|
+
console.log(`AEO month over month: ${data.project} ${data.from.month} -> ${data.to.month}`);
|
|
11875
|
+
const b = data.basket;
|
|
11876
|
+
const excl = [];
|
|
11877
|
+
if (b.excludedFromOnly > 0) excl.push(`${b.excludedFromOnly} only in ${data.from.month}`);
|
|
11878
|
+
if (b.excludedToOnly > 0) excl.push(`${b.excludedToOnly} only in ${data.to.month}`);
|
|
11879
|
+
if (b.excludedProviders.length > 0) excl.push(`engines dropped: ${b.excludedProviders.join(", ")}`);
|
|
11880
|
+
console.log(`Basket: ${b.queryCount} quer${b.queryCount === 1 ? "y" : "ies"}, ${b.providers.length} engine(s)${excl.length ? ` (excluded: ${excl.join("; ")})` : ""}`);
|
|
11881
|
+
const sweeps = `Sweeps: ${data.from.month} ${data.from.runCount}, ${data.to.month} ${data.to.runCount}`;
|
|
11882
|
+
const low = data.from.lowRunCount || data.to.lowRunCount;
|
|
11883
|
+
console.log(low ? `${sweeps} (below the 5-sweep floor \u2014 intervals are wide, a "moved" verdict is unlikely to be reachable)` : sweeps);
|
|
11884
|
+
if (data.continuity.status !== "comparable") {
|
|
11885
|
+
console.log(`Continuity: ${data.continuity.status.replace("-", " ")} \u2014 no directional call is made.`);
|
|
11886
|
+
}
|
|
11887
|
+
console.log("");
|
|
11888
|
+
const rows = data.metrics.map((m) => ({
|
|
11889
|
+
label: `${m.label}${m.driftRobust ? " *" : ""}`,
|
|
11890
|
+
to: periodCell(m.to),
|
|
11891
|
+
from: periodCell(m.from),
|
|
11892
|
+
verdict: verdictCell(m)
|
|
11893
|
+
}));
|
|
11894
|
+
rows.push({
|
|
11895
|
+
label: "Queries named (count)",
|
|
11896
|
+
to: `${data.queriesMentioned.to.count} of ${data.queriesMentioned.to.of}`,
|
|
11897
|
+
from: `${data.queriesMentioned.from.count} of ${data.queriesMentioned.from.of}`,
|
|
11898
|
+
verdict: ""
|
|
11899
|
+
});
|
|
11900
|
+
const w = (sel, head) => Math.max(head.length, ...rows.map((r) => sel(r).length));
|
|
11901
|
+
const lw = w((r) => r.label, "Metric");
|
|
11902
|
+
const tw = w((r) => r.to, data.to.month);
|
|
11903
|
+
const fw = w((r) => r.from, data.from.month);
|
|
11904
|
+
console.log(` ${"Metric".padEnd(lw)} ${data.to.month.padEnd(tw)} ${data.from.month.padEnd(fw)} Verdict`);
|
|
11905
|
+
for (const r of rows) {
|
|
11906
|
+
console.log(` ${r.label.padEnd(lw)} ${r.to.padEnd(tw)} ${r.from.padEnd(fw)} ${r.verdict}`);
|
|
11907
|
+
}
|
|
11908
|
+
console.log("");
|
|
11909
|
+
console.log(" * share of voice is less exposed to broad model-wide naming propensity; model continuity is still required.");
|
|
11910
|
+
for (const provider of data.continuity.providers) {
|
|
11911
|
+
if (provider.status !== "included") {
|
|
11912
|
+
console.log(` Excluded for model continuity: ${provider.provider} (${provider.fromModels.join("/") || "?"} -> ${provider.toModels.join("/") || "?"}; ${provider.status.replace("-", " ")})`);
|
|
11913
|
+
}
|
|
11914
|
+
}
|
|
11915
|
+
}
|
|
11840
11916
|
function citedCell(c) {
|
|
11841
11917
|
return `${c.cited}/${c.total}`;
|
|
11842
11918
|
}
|
|
@@ -11928,6 +12004,7 @@ function printVisibilityStats(data) {
|
|
|
11928
12004
|
|
|
11929
12005
|
// src/cli-commands/visibility-stats.ts
|
|
11930
12006
|
var USAGE4 = "canonry visibility-stats <project> [--since <iso>] [--until <iso>] [--month <YYYY-MM>] [--last-runs <n>] [--by-provider] [--share-of-voice] [--format json|jsonl]";
|
|
12007
|
+
var COMPARE_USAGE = "canonry visibility-compare <project> --from <YYYY-MM> --to <YYYY-MM> [--format json]";
|
|
11931
12008
|
var VISIBILITY_STATS_CLI_COMMANDS = [
|
|
11932
12009
|
{
|
|
11933
12010
|
path: ["visibility-stats"],
|
|
@@ -11956,6 +12033,22 @@ var VISIBILITY_STATS_CLI_COMMANDS = [
|
|
|
11956
12033
|
format: input.format
|
|
11957
12034
|
});
|
|
11958
12035
|
}
|
|
12036
|
+
},
|
|
12037
|
+
{
|
|
12038
|
+
path: ["visibility-compare"],
|
|
12039
|
+
usage: COMPARE_USAGE,
|
|
12040
|
+
options: {
|
|
12041
|
+
from: stringOption(),
|
|
12042
|
+
to: stringOption()
|
|
12043
|
+
},
|
|
12044
|
+
run: async (input) => {
|
|
12045
|
+
const project = requireProject(input, "visibility-compare", COMPARE_USAGE);
|
|
12046
|
+
await showVisibilityCompare(project, {
|
|
12047
|
+
from: getString(input.values, "from"),
|
|
12048
|
+
to: getString(input.values, "to"),
|
|
12049
|
+
format: input.format
|
|
12050
|
+
});
|
|
12051
|
+
}
|
|
11959
12052
|
}
|
|
11960
12053
|
];
|
|
11961
12054
|
|
package/dist/index.js
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import {
|
|
2
2
|
createServer
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-ZZEA774R.js";
|
|
4
4
|
import {
|
|
5
5
|
loadConfig
|
|
6
|
-
} from "./chunk-
|
|
7
|
-
import "./chunk-
|
|
8
|
-
import "./chunk-
|
|
6
|
+
} from "./chunk-PJATAPZW.js";
|
|
7
|
+
import "./chunk-FVVKNMZW.js";
|
|
8
|
+
import "./chunk-IAJ5TQ4S.js";
|
|
9
9
|
export {
|
|
10
10
|
createServer,
|
|
11
11
|
loadConfig
|
package/dist/mcp.js
CHANGED
|
@@ -3,10 +3,10 @@ import {
|
|
|
3
3
|
PACKAGE_VERSION,
|
|
4
4
|
canonryMcpTools,
|
|
5
5
|
createApiClient
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-PJATAPZW.js";
|
|
7
7
|
import {
|
|
8
8
|
isReadOnlyKey
|
|
9
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-IAJ5TQ4S.js";
|
|
10
10
|
|
|
11
11
|
// src/mcp/cli.ts
|
|
12
12
|
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.117.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",
|
|
@@ -66,22 +66,22 @@
|
|
|
66
66
|
"tsup": "^8.5.1",
|
|
67
67
|
"tsx": "^4.19.0",
|
|
68
68
|
"@ainyc/canonry-api-client": "0.0.0",
|
|
69
|
+
"@ainyc/canonry-api-routes": "0.0.0",
|
|
69
70
|
"@ainyc/canonry-config": "0.0.0",
|
|
70
71
|
"@ainyc/canonry-contracts": "0.0.0",
|
|
71
|
-
"@ainyc/canonry-api-routes": "0.0.0",
|
|
72
72
|
"@ainyc/canonry-db": "0.0.0",
|
|
73
73
|
"@ainyc/canonry-integration-bing": "0.0.0",
|
|
74
|
-
"@ainyc/canonry-integration-
|
|
74
|
+
"@ainyc/canonry-integration-openai-ads": "0.0.0",
|
|
75
75
|
"@ainyc/canonry-integration-commoncrawl": "0.0.0",
|
|
76
|
+
"@ainyc/canonry-integration-cloud-run": "0.0.0",
|
|
76
77
|
"@ainyc/canonry-integration-google": "0.0.0",
|
|
77
|
-
"@ainyc/canonry-integration-openai-ads": "0.0.0",
|
|
78
78
|
"@ainyc/canonry-integration-google-business-profile": "0.0.0",
|
|
79
79
|
"@ainyc/canonry-integration-google-places": "0.0.0",
|
|
80
80
|
"@ainyc/canonry-integration-traffic": "0.0.0",
|
|
81
|
+
"@ainyc/canonry-integration-wordpress": "0.0.0",
|
|
82
|
+
"@ainyc/canonry-provider-cdp": "0.0.0",
|
|
81
83
|
"@ainyc/canonry-intelligence": "0.0.0",
|
|
82
84
|
"@ainyc/canonry-provider-claude": "0.0.0",
|
|
83
|
-
"@ainyc/canonry-provider-cdp": "0.0.0",
|
|
84
|
-
"@ainyc/canonry-integration-wordpress": "0.0.0",
|
|
85
85
|
"@ainyc/canonry-provider-gemini": "0.0.0",
|
|
86
86
|
"@ainyc/canonry-provider-openai": "0.0.0",
|
|
87
87
|
"@ainyc/canonry-provider-perplexity": "0.0.0",
|