@ainyc/canonry 3.3.3 → 3.3.9
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 +20 -0
- package/assets/agent-workspace/skills/canonry-setup/SKILL.md +1 -1
- package/assets/agent-workspace/skills/canonry-setup/references/canonry-cli.md +18 -0
- package/dist/{chunk-NCGX6UI4.js → chunk-24C7RMIS.js} +14 -0
- package/dist/{chunk-GH5ILITH.js → chunk-P6D3O5JB.js} +898 -248
- package/dist/cli.js +1077 -94
- package/dist/index.js +2 -2
- package/dist/mcp.js +1 -1
- package/package.json +5 -5
|
@@ -5,6 +5,26 @@ description: Weekly and monthly report templates with metric tables, regression/
|
|
|
5
5
|
|
|
6
6
|
# Reporting Templates
|
|
7
7
|
|
|
8
|
+
## One-Command HTML Report
|
|
9
|
+
|
|
10
|
+
When a client asks for a "current state" or "AEO report" without a specific custom narrative, prefer the bundled report instead of hand-rolling sections:
|
|
11
|
+
|
|
12
|
+
```bash
|
|
13
|
+
canonry report <project> # writes canonry-report-<project>-YYYY-MM-DD.html in cwd
|
|
14
|
+
canonry report <project> --output dist/aeo.html # custom path
|
|
15
|
+
canonry report <project> --format json # raw payload, useful for narrating in chat
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
The HTML is self-contained (inline CSS + SVG charts, no network dependencies) and covers: executive summary, per-keyword × per-provider citation matrix, competitor landscape, AI source origin, GSC + GA4 performance, social and AI referrals, indexing health, citations trend, prioritized insights, and recommended next steps. Same payload is available via `GET /api/v1/projects/<name>/report` and the `canonry_report` MCP tool — use `--format json` when you want to summarize specific numbers in a thread instead of attaching the file.
|
|
19
|
+
|
|
20
|
+
Behaviors worth knowing before narrating numbers from the report:
|
|
21
|
+
- `executiveSummary.citationRate` is always sourced from the latest visibility run (completed **or** partial), so it tracks the scorecard table even when the latest sweep had a flaky provider.
|
|
22
|
+
- `citationsTrend` excludes partial runs. A project with only one completed run shows `trend: "unknown"` — never claim a comparison that isn't there.
|
|
23
|
+
- Project ownership and competitor tagging use subdomain-aware matching: `blog.example.com` counts as the project when `example.com` is the canonical domain or in `ownedDomains`; `blog.rival.com` is tagged `isCompetitor: true` when `rival.com` is tracked.
|
|
24
|
+
- AI referral totals dedupe overlapping GA4 attribution dimensions (`session` / `first_user` / `manual_utm`).
|
|
25
|
+
|
|
26
|
+
The hand-rolled templates below are still the right call when the user wants a focused weekly/monthly digest with custom regression and gain narratives that the bundled report doesn't surface.
|
|
27
|
+
|
|
8
28
|
## Weekly Report
|
|
9
29
|
|
|
10
30
|
```
|
|
@@ -60,7 +60,7 @@ A canonry engagement follows the same loop regardless of project size:
|
|
|
60
60
|
2. **Prioritize** — Triage by impact: indexing gaps → schema gaps → content gaps → keyphrase strategy. Branded-term losses are urgent.
|
|
61
61
|
3. **Execute** — Apply fixes via the canonry CLI or platform integrations. See `references/canonry-cli.md` for the full command catalog and `references/wordpress-integration.md` for the WordPress workflow.
|
|
62
62
|
4. **Monitor** — Re-run sweeps weekly. Correlate visibility shifts with deployments and competitor moves.
|
|
63
|
-
5. **Report** — Lead with data, not interpretation: "Lost `<keyword>` on Gemini between <date> and <date> — two competitors moved in. Here's what to fix."
|
|
63
|
+
5. **Report** — Lead with data, not interpretation: "Lost `<keyword>` on Gemini between <date> and <date> — two competitors moved in. Here's what to fix." For a one-command client-facing summary, run `canonry report <project>` to generate a self-contained HTML bundle (executive summary, citation scorecard, competitor landscape, GSC + GA4 performance, insights). Same payload is available via `--format json` and the `canonry_report` MCP tool.
|
|
64
64
|
|
|
65
65
|
## Common Starting Points
|
|
66
66
|
|
|
@@ -84,6 +84,24 @@ Output shows:
|
|
|
84
84
|
- `✗ not-cited` — domain did not appear
|
|
85
85
|
- Summary: `Cited: X / Y`
|
|
86
86
|
|
|
87
|
+
## Reports
|
|
88
|
+
|
|
89
|
+
```bash
|
|
90
|
+
canonry report <project> # write canonry-report-<project>-YYYY-MM-DD.html
|
|
91
|
+
canonry report <project> --output dist/aeo.html # custom path
|
|
92
|
+
canonry report <project> --format json # raw report payload to stdout
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
One-command client-facing AEO report. Bundles the latest visibility sweep, competitor landscape, AI source origin, GSC + GA4 performance, social and AI referrals, indexing health, citations trend, prioritized insights, and recommended next steps into a self-contained HTML file (inline CSS + SVG charts, no network dependencies). Backed by `GET /api/v1/projects/<name>/report` and the `canonry_report` MCP tool.
|
|
96
|
+
|
|
97
|
+
Behavior to know when narrating numbers from the report:
|
|
98
|
+
- `executiveSummary.citationRate` is sourced from the latest visibility run (completed **or** partial), so it always matches the scorecard table.
|
|
99
|
+
- `citationsTrend` excludes partial runs to avoid skew. A project with only one completed run gets `trend: "unknown"` and the finding "No prior run to compare against." — not "Flat compared to the previous run."
|
|
100
|
+
- Project ownership uses subdomain-aware matching against `project.canonicalDomain` plus any configured `ownedDomains`. `blog.example.com` and `brand.io` count as the project, not as external sources, when those rules apply.
|
|
101
|
+
- Competitor tagging in `aiSourceOrigin.topDomains` uses the same subdomain-aware match — `blog.rival.com` is `isCompetitor: true` when `rival.com` is tracked.
|
|
102
|
+
- AI referral totals dedupe overlapping GA4 attribution dimensions (`session` / `first_user` / `manual_utm`) by picking the largest dimension per `(date, source, medium)`. Two 10-session rows for the same tuple report 10 sessions, not 20.
|
|
103
|
+
- GSC top-query CTR and avgPosition are impression-weighted, matching GSC's own metric semantics across multi-row queries.
|
|
104
|
+
|
|
87
105
|
## Analytics
|
|
88
106
|
|
|
89
107
|
```bash
|
|
@@ -2677,6 +2677,9 @@ var ApiClient = class {
|
|
|
2677
2677
|
`/projects/${encodeURIComponent(project)}/search?${params.toString()}`
|
|
2678
2678
|
);
|
|
2679
2679
|
}
|
|
2680
|
+
async getReport(project) {
|
|
2681
|
+
return this.request("GET", `/projects/${encodeURIComponent(project)}/report`);
|
|
2682
|
+
}
|
|
2680
2683
|
async runDoctor(opts = {}) {
|
|
2681
2684
|
const qs = opts.checkIds && opts.checkIds.length > 0 ? `?check=${encodeURIComponent(opts.checkIds.join(","))}` : "";
|
|
2682
2685
|
const path2 = opts.project ? `/projects/${encodeURIComponent(opts.project)}/doctor${qs}` : `/doctor${qs}`;
|
|
@@ -2952,6 +2955,17 @@ var canonryMcpTools = [
|
|
|
2952
2955
|
openApiOperations: ["GET /api/v1/projects/{name}/overview"],
|
|
2953
2956
|
handler: (client, input) => client.getProjectOverview(input.project)
|
|
2954
2957
|
}),
|
|
2958
|
+
defineTool({
|
|
2959
|
+
name: "canonry_report",
|
|
2960
|
+
title: "Get aggregated AEO report",
|
|
2961
|
+
description: "Returns the full client-facing AEO report bundle for a project \u2014 executive summary, per-keyword \xD7 per-provider citation matrix, competitor landscape, AI source origin, 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 the self-contained HTML.",
|
|
2962
|
+
access: "read",
|
|
2963
|
+
tier: "monitoring",
|
|
2964
|
+
inputSchema: projectInputSchema,
|
|
2965
|
+
annotations: readAnnotations(),
|
|
2966
|
+
openApiOperations: ["GET /api/v1/projects/{name}/report"],
|
|
2967
|
+
handler: (client, input) => client.getReport(input.project)
|
|
2968
|
+
}),
|
|
2955
2969
|
defineTool({
|
|
2956
2970
|
name: "canonry_search",
|
|
2957
2971
|
title: "Search project (composite)",
|