@ainyc/canonry 2.4.5 → 2.5.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 +12 -2
- package/assets/agent-workspace/skills/canonry-setup/SKILL.md +3 -3
- package/assets/agent-workspace/skills/canonry-setup/references/canonry-cli.md +2 -0
- package/assets/agent-workspace/skills/canonry-setup/references/indexing.md +8 -0
- package/assets/assets/{index-Nrl3ecFY.js → index-agELvqT1.js} +14 -14
- package/assets/index.html +1 -1
- package/dist/{chunk-6UY2PETG.js → chunk-TIHU2YXW.js} +378 -128
- package/dist/cli.js +116 -19
- package/dist/index.js +1 -1
- package/package.json +9 -9
package/dist/cli.js
CHANGED
|
@@ -38,7 +38,7 @@ import {
|
|
|
38
38
|
showFirstRunNotice,
|
|
39
39
|
trackEvent,
|
|
40
40
|
usageError
|
|
41
|
-
} from "./chunk-
|
|
41
|
+
} from "./chunk-TIHU2YXW.js";
|
|
42
42
|
import {
|
|
43
43
|
apiKeys,
|
|
44
44
|
competitors,
|
|
@@ -813,6 +813,35 @@ var BACKLINKS_CLI_COMMANDS = [
|
|
|
813
813
|
function getClient2() {
|
|
814
814
|
return createApiClient();
|
|
815
815
|
}
|
|
816
|
+
async function waitForRunStatus(client, runId, config) {
|
|
817
|
+
const start = Date.now();
|
|
818
|
+
process.stderr.write(config.progressLabel);
|
|
819
|
+
while (Date.now() - start < config.timeoutMs) {
|
|
820
|
+
await new Promise((resolve) => setTimeout(resolve, config.intervalMs));
|
|
821
|
+
const current = await client.getRun(runId);
|
|
822
|
+
process.stderr.write(".");
|
|
823
|
+
if (config.successStatuses.includes(current.status)) {
|
|
824
|
+
process.stderr.write("\n");
|
|
825
|
+
return current;
|
|
826
|
+
}
|
|
827
|
+
if (config.failureStatuses.includes(current.status)) {
|
|
828
|
+
process.stderr.write("\n");
|
|
829
|
+
throw new CliError({
|
|
830
|
+
code: config.failureCode,
|
|
831
|
+
message: config.failureMessage,
|
|
832
|
+
displayMessage: config.failureMessage,
|
|
833
|
+
details: { runId, status: current.status, ...config.details ?? {} }
|
|
834
|
+
});
|
|
835
|
+
}
|
|
836
|
+
}
|
|
837
|
+
process.stderr.write("\n");
|
|
838
|
+
throw new CliError({
|
|
839
|
+
code: config.timeoutCode,
|
|
840
|
+
message: config.timeoutMessage,
|
|
841
|
+
displayMessage: config.timeoutMessage,
|
|
842
|
+
details: { runId, ...config.details ?? {} }
|
|
843
|
+
});
|
|
844
|
+
}
|
|
816
845
|
async function bingConnect(project, opts) {
|
|
817
846
|
const apiKey = opts?.apiKey;
|
|
818
847
|
if (!apiKey) {
|
|
@@ -1091,6 +1120,42 @@ async function bingRequestIndexing(project, opts) {
|
|
|
1091
1120
|
console.log(`Summary: ${result.summary.succeeded} succeeded, ${result.summary.failed} failed (${result.summary.total} total)`);
|
|
1092
1121
|
}
|
|
1093
1122
|
}
|
|
1123
|
+
async function bingInspectSitemap(project, opts) {
|
|
1124
|
+
const client = getClient2();
|
|
1125
|
+
const run = await client.bingInspectSitemap(project, {
|
|
1126
|
+
sitemapUrl: opts.sitemapUrl
|
|
1127
|
+
});
|
|
1128
|
+
if (!opts.wait && opts.format === "json") {
|
|
1129
|
+
console.log(JSON.stringify(run, null, 2));
|
|
1130
|
+
return;
|
|
1131
|
+
}
|
|
1132
|
+
if (opts.format !== "json") {
|
|
1133
|
+
console.log(`Bing sitemap inspection started (run ${run.id})`);
|
|
1134
|
+
}
|
|
1135
|
+
if (opts.wait) {
|
|
1136
|
+
const current = await waitForRunStatus(client, run.id, {
|
|
1137
|
+
timeoutMs: 30 * 60 * 1e3,
|
|
1138
|
+
intervalMs: 3e3,
|
|
1139
|
+
progressLabel: "Waiting for Bing sitemap inspection to complete",
|
|
1140
|
+
successStatuses: ["completed", "partial"],
|
|
1141
|
+
failureStatuses: ["failed"],
|
|
1142
|
+
timeoutCode: "BING_INSPECT_SITEMAP_TIMEOUT",
|
|
1143
|
+
failureCode: "BING_INSPECT_SITEMAP_FAILED",
|
|
1144
|
+
timeoutMessage: "Timed out waiting for Bing sitemap inspection to complete.",
|
|
1145
|
+
failureMessage: "Bing sitemap inspection failed.",
|
|
1146
|
+
details: { project }
|
|
1147
|
+
});
|
|
1148
|
+
if (opts.format === "json") {
|
|
1149
|
+
console.log(JSON.stringify(current, null, 2));
|
|
1150
|
+
return;
|
|
1151
|
+
}
|
|
1152
|
+
if (current.status === "partial") {
|
|
1153
|
+
console.log("Bing sitemap inspection completed with some errors.");
|
|
1154
|
+
return;
|
|
1155
|
+
}
|
|
1156
|
+
console.log("Bing sitemap inspection completed successfully.");
|
|
1157
|
+
}
|
|
1158
|
+
}
|
|
1094
1159
|
async function bingPerformance(project, format) {
|
|
1095
1160
|
const client = getClient2();
|
|
1096
1161
|
const rows = await client.bingPerformance(project);
|
|
@@ -1222,6 +1287,22 @@ var BING_CLI_COMMANDS = [
|
|
|
1222
1287
|
});
|
|
1223
1288
|
}
|
|
1224
1289
|
},
|
|
1290
|
+
{
|
|
1291
|
+
path: ["bing", "inspect-sitemap"],
|
|
1292
|
+
usage: "canonry bing inspect-sitemap <project> [--sitemap-url <url>] [--wait] [--format json]",
|
|
1293
|
+
options: {
|
|
1294
|
+
"sitemap-url": stringOption(),
|
|
1295
|
+
wait: { type: "boolean", default: false }
|
|
1296
|
+
},
|
|
1297
|
+
run: async (input) => {
|
|
1298
|
+
const project = requireProject(input, "bing.inspect-sitemap", "canonry bing inspect-sitemap <project> [--sitemap-url <url>] [--wait] [--format json]");
|
|
1299
|
+
await bingInspectSitemap(project, {
|
|
1300
|
+
sitemapUrl: getString(input.values, "sitemap-url"),
|
|
1301
|
+
wait: getBoolean(input.values, "wait"),
|
|
1302
|
+
format: input.format
|
|
1303
|
+
});
|
|
1304
|
+
}
|
|
1305
|
+
},
|
|
1225
1306
|
{
|
|
1226
1307
|
path: ["bing", "request-indexing"],
|
|
1227
1308
|
usage: "canonry bing request-indexing <project> [url] [--all-unindexed] [--format json]",
|
|
@@ -1266,12 +1347,12 @@ var BING_CLI_COMMANDS = [
|
|
|
1266
1347
|
},
|
|
1267
1348
|
{
|
|
1268
1349
|
path: ["bing"],
|
|
1269
|
-
usage: "canonry bing <connect|disconnect|status|sites|set-site|coverage|coverage-history|inspect|inspections|request-indexing|performance|refresh> <project> [args]",
|
|
1350
|
+
usage: "canonry bing <connect|disconnect|status|sites|set-site|coverage|coverage-history|inspect|inspect-sitemap|inspections|request-indexing|performance|refresh> <project> [args]",
|
|
1270
1351
|
run: async (input) => {
|
|
1271
1352
|
unknownSubcommand(input.positionals[0], {
|
|
1272
1353
|
command: "bing",
|
|
1273
|
-
usage: "canonry bing <connect|disconnect|status|sites|set-site|coverage|coverage-history|inspect|inspections|request-indexing|performance|refresh> <project> [args]",
|
|
1274
|
-
available: ["connect", "disconnect", "status", "sites", "set-site", "coverage", "coverage-history", "inspect", "inspections", "request-indexing", "performance", "refresh"]
|
|
1354
|
+
usage: "canonry bing <connect|disconnect|status|sites|set-site|coverage|coverage-history|inspect|inspect-sitemap|inspections|request-indexing|performance|refresh> <project> [args]",
|
|
1355
|
+
available: ["connect", "disconnect", "status", "sites", "set-site", "coverage", "coverage-history", "inspect", "inspect-sitemap", "inspections", "request-indexing", "performance", "refresh"]
|
|
1275
1356
|
});
|
|
1276
1357
|
}
|
|
1277
1358
|
}
|
|
@@ -2181,10 +2262,11 @@ var COMPETITOR_CLI_COMMANDS = [
|
|
|
2181
2262
|
];
|
|
2182
2263
|
|
|
2183
2264
|
// src/commands/google.ts
|
|
2265
|
+
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
2266
|
function getClient6() {
|
|
2185
2267
|
return createApiClient();
|
|
2186
2268
|
}
|
|
2187
|
-
async function
|
|
2269
|
+
async function waitForRunStatus2(client, runId, config) {
|
|
2188
2270
|
const start = Date.now();
|
|
2189
2271
|
process.stderr.write(config.progressLabel);
|
|
2190
2272
|
while (Date.now() - start < config.timeoutMs) {
|
|
@@ -2328,7 +2410,7 @@ async function googleSync(project, opts) {
|
|
|
2328
2410
|
console.log(`GSC sync started (run ${run.id})`);
|
|
2329
2411
|
}
|
|
2330
2412
|
if (opts.wait) {
|
|
2331
|
-
const current = await
|
|
2413
|
+
const current = await waitForRunStatus2(client, run.id, {
|
|
2332
2414
|
timeoutMs: 10 * 60 * 1e3,
|
|
2333
2415
|
intervalMs: 2e3,
|
|
2334
2416
|
progressLabel: "Waiting for sync to complete",
|
|
@@ -2518,7 +2600,7 @@ async function googleInspectSitemap(project, opts) {
|
|
|
2518
2600
|
console.log(`Sitemap inspection started (run ${run.id})`);
|
|
2519
2601
|
}
|
|
2520
2602
|
if (opts.wait) {
|
|
2521
|
-
const current = await
|
|
2603
|
+
const current = await waitForRunStatus2(client, run.id, {
|
|
2522
2604
|
timeoutMs: 30 * 60 * 1e3,
|
|
2523
2605
|
intervalMs: 3e3,
|
|
2524
2606
|
progressLabel: "Waiting for sitemap inspection to complete",
|
|
@@ -2586,7 +2668,7 @@ Primary sitemap: ${result.primarySitemapUrl}`);
|
|
|
2586
2668
|
console.log(`Sitemap URL saved. Inspection run queued (run ${result.run.id}).`);
|
|
2587
2669
|
}
|
|
2588
2670
|
if (opts.wait) {
|
|
2589
|
-
const current = await
|
|
2671
|
+
const current = await waitForRunStatus2(client, result.run.id, {
|
|
2590
2672
|
timeoutMs: 30 * 60 * 1e3,
|
|
2591
2673
|
intervalMs: 3e3,
|
|
2592
2674
|
progressLabel: "Waiting for sitemap inspection to complete",
|
|
@@ -2630,27 +2712,32 @@ async function googleRequestIndexing(project, opts) {
|
|
|
2630
2712
|
details: { command: "google.request-indexing" }
|
|
2631
2713
|
});
|
|
2632
2714
|
}
|
|
2715
|
+
if (opts.format !== "json") {
|
|
2716
|
+
console.error(INDEXING_API_SCOPE_NOTICE);
|
|
2717
|
+
console.error();
|
|
2718
|
+
}
|
|
2633
2719
|
const result = await client.googleRequestIndexing(project, body);
|
|
2634
2720
|
let indexingConfirmed = false;
|
|
2721
|
+
const lastInspection = /* @__PURE__ */ new Map();
|
|
2635
2722
|
if (opts.wait && result.results.some((r) => r.status === "success")) {
|
|
2636
2723
|
const successUrls = result.results.filter((r) => r.status === "success").map((r) => r.url);
|
|
2637
|
-
const timeout = 10 * 60 * 1e3;
|
|
2724
|
+
const timeout = opts.waitTimeoutMs ?? 10 * 60 * 1e3;
|
|
2725
|
+
const pollInterval = opts.waitPollIntervalMs ?? 1e4;
|
|
2638
2726
|
const start = Date.now();
|
|
2639
|
-
process.stderr.write("
|
|
2727
|
+
process.stderr.write("Polling URL Inspection for indexed verdict");
|
|
2640
2728
|
while (Date.now() - start < timeout) {
|
|
2641
|
-
await new Promise((r) => setTimeout(r,
|
|
2729
|
+
await new Promise((r) => setTimeout(r, pollInterval));
|
|
2642
2730
|
process.stderr.write(".");
|
|
2643
2731
|
let allIndexed = true;
|
|
2644
2732
|
for (const url of successUrls) {
|
|
2645
2733
|
try {
|
|
2646
2734
|
const inspection = await client.gscInspect(project, url);
|
|
2647
|
-
|
|
2735
|
+
lastInspection.set(url, inspection);
|
|
2736
|
+
if (inspection.verdict !== "PASS") {
|
|
2648
2737
|
allIndexed = false;
|
|
2649
|
-
break;
|
|
2650
2738
|
}
|
|
2651
2739
|
} catch {
|
|
2652
2740
|
allIndexed = false;
|
|
2653
|
-
break;
|
|
2654
2741
|
}
|
|
2655
2742
|
}
|
|
2656
2743
|
if (allIndexed) {
|
|
@@ -2661,13 +2748,23 @@ async function googleRequestIndexing(project, opts) {
|
|
|
2661
2748
|
}
|
|
2662
2749
|
if (!indexingConfirmed) {
|
|
2663
2750
|
process.stderr.write("\n");
|
|
2751
|
+
const observed = successUrls.map((url) => {
|
|
2752
|
+
const i = lastInspection.get(url);
|
|
2753
|
+
return {
|
|
2754
|
+
url,
|
|
2755
|
+
verdict: i?.verdict ?? null,
|
|
2756
|
+
coverageState: i?.coverageState ?? null,
|
|
2757
|
+
indexingState: i?.indexingState ?? null
|
|
2758
|
+
};
|
|
2759
|
+
});
|
|
2664
2760
|
throw new CliError({
|
|
2665
2761
|
code: "GOOGLE_INDEXING_CONFIRMATION_TIMEOUT",
|
|
2666
|
-
message: "Timed out waiting for
|
|
2667
|
-
displayMessage: "Timed out waiting for
|
|
2762
|
+
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>`.",
|
|
2763
|
+
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
2764
|
details: {
|
|
2669
2765
|
project,
|
|
2670
|
-
urls: successUrls
|
|
2766
|
+
urls: successUrls,
|
|
2767
|
+
lastObserved: observed
|
|
2671
2768
|
}
|
|
2672
2769
|
});
|
|
2673
2770
|
}
|
|
@@ -2692,7 +2789,7 @@ async function googleRequestIndexing(project, opts) {
|
|
|
2692
2789
|
console.log(`Summary: ${result.summary.succeeded} succeeded, ${result.summary.failed} failed (${result.summary.total} total)`);
|
|
2693
2790
|
}
|
|
2694
2791
|
if (indexingConfirmed) {
|
|
2695
|
-
console.log("
|
|
2792
|
+
console.log("URL Inspection now reports verdict=PASS for the requested URLs (indexed in Google Search).");
|
|
2696
2793
|
}
|
|
2697
2794
|
}
|
|
2698
2795
|
async function googleRefresh(project, format) {
|
|
@@ -2701,7 +2798,7 @@ async function googleRefresh(project, format) {
|
|
|
2701
2798
|
if (format !== "json") {
|
|
2702
2799
|
process.stderr.write("Refreshing GSC coverage data");
|
|
2703
2800
|
}
|
|
2704
|
-
const current = await
|
|
2801
|
+
const current = await waitForRunStatus2(client, run.id, {
|
|
2705
2802
|
timeoutMs: 10 * 60 * 1e3,
|
|
2706
2803
|
intervalMs: 2e3,
|
|
2707
2804
|
progressLabel: "",
|
package/dist/index.js
CHANGED
package/package.json
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ainyc/canonry",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.5.0",
|
|
4
4
|
"type": "module",
|
|
5
|
-
"description": "
|
|
5
|
+
"description": "Agent-first open-source AEO operating platform - track how answer engines cite your domain",
|
|
6
6
|
"license": "FSL-1.1-ALv2",
|
|
7
7
|
"homepage": "https://ainyc.ai",
|
|
8
8
|
"repository": {
|
|
@@ -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-
|
|
61
|
+
"@ainyc/canonry-config": "0.0.0",
|
|
62
|
+
"@ainyc/canonry-db": "0.0.0",
|
|
63
63
|
"@ainyc/canonry-contracts": "0.0.0",
|
|
64
|
+
"@ainyc/canonry-intelligence": "0.0.0",
|
|
64
65
|
"@ainyc/canonry-integration-bing": "0.0.0",
|
|
65
|
-
"@ainyc/canonry-config": "0.0.0",
|
|
66
66
|
"@ainyc/canonry-integration-commoncrawl": "0.0.0",
|
|
67
67
|
"@ainyc/canonry-integration-google": "0.0.0",
|
|
68
68
|
"@ainyc/canonry-integration-wordpress": "0.0.0",
|
|
69
|
-
"@ainyc/canonry-provider-
|
|
70
|
-
"@ainyc/canonry-provider-local": "0.0.0",
|
|
69
|
+
"@ainyc/canonry-provider-claude": "0.0.0",
|
|
71
70
|
"@ainyc/canonry-provider-cdp": "0.0.0",
|
|
71
|
+
"@ainyc/canonry-provider-local": "0.0.0",
|
|
72
72
|
"@ainyc/canonry-provider-openai": "0.0.0",
|
|
73
|
-
"@ainyc/canonry-provider-
|
|
74
|
-
"@ainyc/canonry-provider-
|
|
73
|
+
"@ainyc/canonry-provider-gemini": "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",
|