@ainyc/canonry 2.4.5 → 2.4.6

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.
Files changed (3) hide show
  1. package/README.md +11 -1
  2. package/dist/cli.js +26 -10
  3. package/package.json +10 -10
package/README.md CHANGED
@@ -166,7 +166,17 @@ Integration setup guides: [Google Search Console](docs/google-search-console-set
166
166
 
167
167
  ## Skills
168
168
 
169
- Canonry ships a bundled `canonry-setup` skill that documents the CLI commands, provider setup, analysis workflows, and troubleshooting patterns an agent needs to operate the platform. **Claude Code** picks up the skill automatically from `.claude/skills/canonry-setup/` when you open this repo.
169
+ Canonry ships a bundled `canonry-setup` skill that turns Aero (or any Claude-powered agent) into an AEO/SEO operator. **Claude Code** picks it up automatically from `.claude/skills/canonry-setup/` when you open this repo; the same content lives under [`skills/canonry-setup/`](skills/canonry-setup/) for portable use with other harnesses.
170
+
171
+ The skill covers the end-to-end answer-engine optimization loop:
172
+
173
+ - **AEO monitoring.** Running citation sweeps across Gemini, ChatGPT, Claude, and Perplexity via `canonry run` / `canonry evidence` / `canonry status`, including how to interpret per-phrase citation state and regressions.
174
+ - **Technical SEO audits.** Driving the companion [`@ainyc/aeo-audit`](https://www.npmjs.com/package/@ainyc/aeo-audit) CLI for 14-factor scoring — structured data (JSON-LD), content depth, AI-readable files (`llms.txt`, `llms-full.txt`), E-E-A-T signals, FAQ blocks, definition blocks, H1/alt/meta hygiene.
175
+ - **Indexing diagnosis.** Google Search Console and Bing Webmaster Tools coverage, URL inspection, and one-shot submissions via `canonry google request-indexing` / `canonry bing request-indexing`.
176
+ - **Schema & content execution.** Patterns for injecting LocalBusiness/FAQPage JSON-LD, writing `llms.txt` with service-area detail, trimming keyphrase lists to high-intent queries, and handling WordPress/Elementor specifics (REST API, Application Passwords, Elementor Custom Code).
177
+ - **Diagnose → prioritize → execute → monitor → report workflow.** Opinionated defaults for new sites (0 citations), regressions on established sites, and county-level targeting — with guardrails like "never fabricate citation data" and "back up `~/.canonry/config.yaml` before editing".
178
+
179
+ See [`skills/canonry-setup/SKILL.md`](skills/canonry-setup/SKILL.md) plus the reference files under [`skills/canonry-setup/references/`](skills/canonry-setup/references/) (`canonry-cli.md`, `aeo-analysis.md`, `indexing.md`, `wordpress-integration.md`) for the full playbook. Aero loads the same material natively, so anything an external agent can do through the skill, Aero can do from the CLI or dashboard command bar.
170
180
 
171
181
  ## Deployment
172
182
 
package/dist/cli.js CHANGED
@@ -2181,6 +2181,7 @@ var COMPETITOR_CLI_COMMANDS = [
2181
2181
  ];
2182
2182
 
2183
2183
  // src/commands/google.ts
2184
+ var INDEXING_API_SCOPE_NOTICE = "Note: Google's Indexing API officially supports only pages with JobPosting or BroadcastEvent (livestream VideoObject) structured data. For other URL types, submissions are accepted (HTTP 200) but not guaranteed to be prioritized for crawling. For general pages, submit a sitemap and use URL Inspection to monitor status.";
2184
2185
  function getClient6() {
2185
2186
  return createApiClient();
2186
2187
  }
@@ -2630,27 +2631,32 @@ async function googleRequestIndexing(project, opts) {
2630
2631
  details: { command: "google.request-indexing" }
2631
2632
  });
2632
2633
  }
2634
+ if (opts.format !== "json") {
2635
+ console.error(INDEXING_API_SCOPE_NOTICE);
2636
+ console.error();
2637
+ }
2633
2638
  const result = await client.googleRequestIndexing(project, body);
2634
2639
  let indexingConfirmed = false;
2640
+ const lastInspection = /* @__PURE__ */ new Map();
2635
2641
  if (opts.wait && result.results.some((r) => r.status === "success")) {
2636
2642
  const successUrls = result.results.filter((r) => r.status === "success").map((r) => r.url);
2637
- const timeout = 10 * 60 * 1e3;
2643
+ const timeout = opts.waitTimeoutMs ?? 10 * 60 * 1e3;
2644
+ const pollInterval = opts.waitPollIntervalMs ?? 1e4;
2638
2645
  const start = Date.now();
2639
- process.stderr.write("Waiting for indexing confirmation");
2646
+ process.stderr.write("Polling URL Inspection for indexed verdict");
2640
2647
  while (Date.now() - start < timeout) {
2641
- await new Promise((r) => setTimeout(r, 1e4));
2648
+ await new Promise((r) => setTimeout(r, pollInterval));
2642
2649
  process.stderr.write(".");
2643
2650
  let allIndexed = true;
2644
2651
  for (const url of successUrls) {
2645
2652
  try {
2646
2653
  const inspection = await client.gscInspect(project, url);
2647
- if (inspection.indexingState !== "INDEXING_ALLOWED") {
2654
+ lastInspection.set(url, inspection);
2655
+ if (inspection.verdict !== "PASS") {
2648
2656
  allIndexed = false;
2649
- break;
2650
2657
  }
2651
2658
  } catch {
2652
2659
  allIndexed = false;
2653
- break;
2654
2660
  }
2655
2661
  }
2656
2662
  if (allIndexed) {
@@ -2661,13 +2667,23 @@ async function googleRequestIndexing(project, opts) {
2661
2667
  }
2662
2668
  if (!indexingConfirmed) {
2663
2669
  process.stderr.write("\n");
2670
+ const observed = successUrls.map((url) => {
2671
+ const i = lastInspection.get(url);
2672
+ return {
2673
+ url,
2674
+ verdict: i?.verdict ?? null,
2675
+ coverageState: i?.coverageState ?? null,
2676
+ indexingState: i?.indexingState ?? null
2677
+ };
2678
+ });
2664
2679
  throw new CliError({
2665
2680
  code: "GOOGLE_INDEXING_CONFIRMATION_TIMEOUT",
2666
- message: "Timed out waiting for indexing confirmation. URLs may still be processing.",
2667
- displayMessage: "Timed out waiting for indexing confirmation. URLs may still be processing.",
2681
+ message: "Timed out waiting for Google to report verdict=PASS. Google typically takes hours to days to index new URLs, so this is expected and does not mean the submission failed. Re-check later with `canonry google gsc inspect <url>`.",
2682
+ displayMessage: "Timed out waiting for Google to report verdict=PASS. Google typically takes hours to days to index new URLs \u2014 this is not a failure. Re-check later with `canonry google gsc inspect <url>`.",
2668
2683
  details: {
2669
2684
  project,
2670
- urls: successUrls
2685
+ urls: successUrls,
2686
+ lastObserved: observed
2671
2687
  }
2672
2688
  });
2673
2689
  }
@@ -2692,7 +2708,7 @@ async function googleRequestIndexing(project, opts) {
2692
2708
  console.log(`Summary: ${result.summary.succeeded} succeeded, ${result.summary.failed} failed (${result.summary.total} total)`);
2693
2709
  }
2694
2710
  if (indexingConfirmed) {
2695
- console.log("All requested URLs are now indexed.");
2711
+ console.log("URL Inspection now reports verdict=PASS for the requested URLs (indexed in Google Search).");
2696
2712
  }
2697
2713
  }
2698
2714
  async function googleRefresh(project, format) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ainyc/canonry",
3
- "version": "2.4.5",
3
+ "version": "2.4.6",
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",
@@ -57,21 +57,21 @@
57
57
  "@types/node-cron": "^3.0.11",
58
58
  "tsup": "^8.5.1",
59
59
  "tsx": "^4.19.0",
60
- "@ainyc/canonry-db": "0.0.0",
61
60
  "@ainyc/canonry-api-routes": "0.0.0",
62
- "@ainyc/canonry-intelligence": "0.0.0",
63
- "@ainyc/canonry-contracts": "0.0.0",
64
- "@ainyc/canonry-integration-bing": "0.0.0",
65
61
  "@ainyc/canonry-config": "0.0.0",
66
- "@ainyc/canonry-integration-commoncrawl": "0.0.0",
62
+ "@ainyc/canonry-contracts": "0.0.0",
63
+ "@ainyc/canonry-intelligence": "0.0.0",
64
+ "@ainyc/canonry-db": "0.0.0",
67
65
  "@ainyc/canonry-integration-google": "0.0.0",
66
+ "@ainyc/canonry-integration-bing": "0.0.0",
67
+ "@ainyc/canonry-provider-cdp": "0.0.0",
68
68
  "@ainyc/canonry-integration-wordpress": "0.0.0",
69
- "@ainyc/canonry-provider-gemini": "0.0.0",
69
+ "@ainyc/canonry-provider-claude": "0.0.0",
70
+ "@ainyc/canonry-integration-commoncrawl": "0.0.0",
70
71
  "@ainyc/canonry-provider-local": "0.0.0",
71
- "@ainyc/canonry-provider-cdp": "0.0.0",
72
+ "@ainyc/canonry-provider-gemini": "0.0.0",
72
73
  "@ainyc/canonry-provider-openai": "0.0.0",
73
- "@ainyc/canonry-provider-perplexity": "0.0.0",
74
- "@ainyc/canonry-provider-claude": "0.0.0"
74
+ "@ainyc/canonry-provider-perplexity": "0.0.0"
75
75
  },
76
76
  "scripts": {
77
77
  "build": "tsx scripts/copy-agent-assets.ts && tsup && tsx build-web.ts",