@ainyc/canonry 4.80.0 → 4.81.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.
Files changed (25) hide show
  1. package/assets/agent-workspace/skills/canonry/references/canonry-cli.md +20 -12
  2. package/assets/assets/{BacklinksPage-dRc62jAY.js → BacklinksPage-DHShKKpo.js} +1 -1
  3. package/assets/assets/{ChartPrimitives-D2_IvTkk.js → ChartPrimitives-udHScxjY.js} +1 -1
  4. package/assets/assets/ProjectPage-BsS1anh7.js +6 -0
  5. package/assets/assets/{RunRow-C0MA3yuQ.js → RunRow-CXyPHMVQ.js} +1 -1
  6. package/assets/assets/{RunsPage-4uxTYgGy.js → RunsPage-BpQ_NpFt.js} +1 -1
  7. package/assets/assets/{SettingsPage-3-SLhcJ7.js → SettingsPage-1ep4ch7n.js} +1 -1
  8. package/assets/assets/{TrafficPage-DZ50qwme.js → TrafficPage-C3Hx-sE7.js} +1 -1
  9. package/assets/assets/TrafficSourceDetailPage-B26n2R6G.js +1 -0
  10. package/assets/assets/{arrow-left-BaZIkAXX.js → arrow-left-Dc_IPJxw.js} +1 -1
  11. package/assets/assets/{extract-error-message-cpvfuFqW.js → extract-error-message-B3PoKkHW.js} +1 -1
  12. package/assets/assets/{index-EnY_OBRd.js → index-DhdFTQkU.js} +86 -86
  13. package/assets/assets/{trash-2-JpcztiS5.js → trash-2-BQ69cGl0.js} +1 -1
  14. package/assets/index.html +1 -1
  15. package/dist/{chunk-2QBSRHSN.js → chunk-6XOZSS3Y.js} +72 -8
  16. package/dist/{chunk-AVN6Q6LM.js → chunk-GMT3YPLT.js} +76 -2
  17. package/dist/{chunk-CXIGHPBE.js → chunk-UAQ42NVJ.js} +440 -123
  18. package/dist/{chunk-LCABGFYN.js → chunk-VX5C7DK7.js} +404 -242
  19. package/dist/cli.js +103 -8
  20. package/dist/index.js +4 -4
  21. package/dist/{intelligence-service-ZWW3I3NL.js → intelligence-service-CAAQAKPN.js} +2 -2
  22. package/dist/mcp.js +2 -2
  23. package/package.json +8 -8
  24. package/assets/assets/ProjectPage-DSuvRUIf.js +0 -6
  25. package/assets/assets/TrafficSourceDetailPage-CzK5TMFp.js +0 -1
package/dist/cli.js CHANGED
@@ -27,7 +27,7 @@ import {
27
27
  setTelemetrySource,
28
28
  showFirstRunNotice,
29
29
  trackEvent
30
- } from "./chunk-LCABGFYN.js";
30
+ } from "./chunk-VX5C7DK7.js";
31
31
  import {
32
32
  CliError,
33
33
  EXIT_SYSTEM_ERROR,
@@ -44,7 +44,7 @@ import {
44
44
  saveConfig,
45
45
  saveConfigPatch,
46
46
  usageError
47
- } from "./chunk-2QBSRHSN.js";
47
+ } from "./chunk-6XOZSS3Y.js";
48
48
  import {
49
49
  apiKeys,
50
50
  createClient,
@@ -52,14 +52,16 @@ import {
52
52
  projects,
53
53
  queries,
54
54
  renderReportHtml
55
- } from "./chunk-CXIGHPBE.js";
55
+ } from "./chunk-UAQ42NVJ.js";
56
56
  import {
57
+ BacklinkSources,
57
58
  CcReleaseSyncStatuses,
58
59
  CheckScopes,
59
60
  CheckStatuses,
60
61
  CitationStates,
61
62
  RunStatuses,
62
63
  TrafficEventKinds,
64
+ backlinkSourceSchema,
63
65
  discoveryBucketSchema,
64
66
  discoveryCompetitorTypeSchema,
65
67
  effectiveDomains,
@@ -73,7 +75,7 @@ import {
73
75
  providerQuotaPolicySchema,
74
76
  resolveProviderInput,
75
77
  winnabilityClassSchema
76
- } from "./chunk-AVN6Q6LM.js";
78
+ } from "./chunk-GMT3YPLT.js";
77
79
 
78
80
  // src/cli.ts
79
81
  import { pathToFileURL } from "url";
@@ -441,6 +443,17 @@ function emitJsonl(records) {
441
443
  }
442
444
 
443
445
  // src/commands/backlinks.ts
446
+ function parseSourceFlag(value) {
447
+ if (value === void 0) return void 0;
448
+ const parsed = backlinkSourceSchema.safeParse(value);
449
+ if (!parsed.success) {
450
+ throw new CliError({
451
+ code: "VALIDATION_ERROR",
452
+ message: `Invalid --source "${value}". Expected one of: ${Object.values(BacklinkSources).join(", ")}.`
453
+ });
454
+ }
455
+ return parsed.data;
456
+ }
444
457
  function getClient() {
445
458
  return createApiClient();
446
459
  }
@@ -472,8 +485,10 @@ function formatSync(sync) {
472
485
  function formatSummaryAndDomains(project, response) {
473
486
  const lines = [];
474
487
  lines.push(`Project: ${project}`);
488
+ lines.push(`Source: ${response.source}`);
475
489
  if (!response.summary) {
476
- lines.push("No ready release \u2014 run `canonry backlinks sync --release <id>` first.");
490
+ const hint = response.source === BacklinkSources["bing-webmaster"] ? "No Bing inbound links yet \u2014 run `canonry backlinks bing-sync <project>` (Bing must be connected)." : "No ready release \u2014 run `canonry backlinks sync --release <id>` first.";
491
+ lines.push(hint);
477
492
  return lines.join("\n");
478
493
  }
479
494
  const s = response.summary;
@@ -619,7 +634,8 @@ async function backlinksList(opts) {
619
634
  const response = await client.backlinksDomains(opts.project, {
620
635
  limit: opts.limit ?? 50,
621
636
  release: opts.release,
622
- excludeCrawlers: opts.excludeCrawlers
637
+ excludeCrawlers: opts.excludeCrawlers,
638
+ source: opts.source
623
639
  });
624
640
  if (opts.format === "json") {
625
641
  printJson(response);
@@ -632,6 +648,45 @@ async function backlinksList(opts) {
632
648
  }
633
649
  console.log(formatSummaryAndDomains(opts.project, response));
634
650
  }
651
+ function formatSourceAvailability(res) {
652
+ const lines = [];
653
+ lines.push(`Project: ${res.projectId} Target: ${res.targetDomain}`);
654
+ lines.push("");
655
+ lines.push("Source Connected Data Linking domains Latest window");
656
+ for (const s of res.sources) {
657
+ lines.push(
658
+ `${s.source.padEnd(15)} ${(s.connected ? "yes" : "no").padEnd(10)} ${(s.hasData ? "yes" : "no").padEnd(6)} ${String(s.totalLinkingDomains).padStart(15)} ${s.latestRelease ?? "\u2014"}`
659
+ );
660
+ }
661
+ if (!res.anyConnected) {
662
+ lines.push("");
663
+ lines.push("No backlink source is set up. Enable Common Crawl (`canonry project \u2026 autoExtractBacklinks`");
664
+ lines.push("+ `canonry backlinks sync`) or connect Bing (`canonry bing connect <project> --api-key <key>`).");
665
+ }
666
+ return lines.join("\n");
667
+ }
668
+ async function backlinksSources(opts) {
669
+ const res = await getClient().backlinksSources(opts.project, { excludeCrawlers: opts.excludeCrawlers });
670
+ if (opts.format === "json") {
671
+ printJson(res);
672
+ return;
673
+ } else if (opts.format === "jsonl") {
674
+ emitJsonl(res.sources.map((s) => ({ project: opts.project, targetDomain: res.targetDomain, ...s })));
675
+ return;
676
+ }
677
+ console.log(formatSourceAvailability(res));
678
+ }
679
+ async function backlinksBingSync(opts) {
680
+ const client = getClient();
681
+ const run = await client.backlinksBingSync(opts.project);
682
+ const final = opts.wait ? await pollRun(run.id, opts.format) : run;
683
+ if (isMachineFormat(opts.format)) {
684
+ printJson(final);
685
+ return;
686
+ }
687
+ if (opts.wait) process.stderr.write("\n");
688
+ console.log(`Bing sync run ${final.id} (${final.status})${final.error ? " \u2014 " + formatRunErrorOneLine(final.error) : ""}`);
689
+ }
635
690
  async function backlinksReleases(opts = {}) {
636
691
  const rows = await getClient().backlinksCachedReleases();
637
692
  if (opts.format === "json") {
@@ -709,17 +764,18 @@ var BACKLINKS_CLI_COMMANDS = [
709
764
  },
710
765
  {
711
766
  path: ["backlinks", "list"],
712
- usage: "canonry backlinks list <project> [--limit <n>] [--release <id>] [--exclude-crawlers] [--format json]",
767
+ usage: "canonry backlinks list <project> [--source commoncrawl|bing-webmaster] [--limit <n>] [--release <id>] [--exclude-crawlers] [--format json|jsonl]",
713
768
  options: {
714
769
  limit: stringOption(),
715
770
  release: stringOption(),
771
+ source: stringOption(),
716
772
  "exclude-crawlers": { type: "boolean" }
717
773
  },
718
774
  run: async (input) => {
719
775
  const project = requireProject(
720
776
  input,
721
777
  "backlinks list",
722
- "canonry backlinks list <project> [--limit <n>] [--release <id>] [--exclude-crawlers]"
778
+ "canonry backlinks list <project> [--source commoncrawl|bing-webmaster] [--limit <n>] [--release <id>] [--exclude-crawlers]"
723
779
  );
724
780
  const limit = parseIntegerOption(input, "limit", {
725
781
  message: "--limit must be an integer",
@@ -730,11 +786,50 @@ var BACKLINKS_CLI_COMMANDS = [
730
786
  project,
731
787
  limit,
732
788
  release: getString(input.values, "release"),
789
+ source: parseSourceFlag(getString(input.values, "source")),
790
+ excludeCrawlers: getBoolean(input.values, "exclude-crawlers"),
791
+ format: input.format
792
+ });
793
+ }
794
+ },
795
+ {
796
+ path: ["backlinks", "sources"],
797
+ usage: "canonry backlinks sources <project> [--exclude-crawlers] [--format json|jsonl]",
798
+ options: {
799
+ "exclude-crawlers": { type: "boolean" }
800
+ },
801
+ run: async (input) => {
802
+ const project = requireProject(
803
+ input,
804
+ "backlinks sources",
805
+ "canonry backlinks sources <project>"
806
+ );
807
+ await backlinksSources({
808
+ project,
733
809
  excludeCrawlers: getBoolean(input.values, "exclude-crawlers"),
734
810
  format: input.format
735
811
  });
736
812
  }
737
813
  },
814
+ {
815
+ path: ["backlinks", "bing-sync"],
816
+ usage: "canonry backlinks bing-sync <project> [--wait] [--format json]",
817
+ options: {
818
+ wait: { type: "boolean" }
819
+ },
820
+ run: async (input) => {
821
+ const project = requireProject(
822
+ input,
823
+ "backlinks bing-sync",
824
+ "canonry backlinks bing-sync <project> [--wait]"
825
+ );
826
+ await backlinksBingSync({
827
+ project,
828
+ wait: getBoolean(input.values, "wait"),
829
+ format: input.format
830
+ });
831
+ }
832
+ },
738
833
  {
739
834
  path: ["backlinks", "releases"],
740
835
  usage: "canonry backlinks releases [--format json]",
package/dist/index.js CHANGED
@@ -1,11 +1,11 @@
1
1
  import {
2
2
  createServer
3
- } from "./chunk-LCABGFYN.js";
3
+ } from "./chunk-VX5C7DK7.js";
4
4
  import {
5
5
  loadConfig
6
- } from "./chunk-2QBSRHSN.js";
7
- import "./chunk-CXIGHPBE.js";
8
- import "./chunk-AVN6Q6LM.js";
6
+ } from "./chunk-6XOZSS3Y.js";
7
+ import "./chunk-UAQ42NVJ.js";
8
+ import "./chunk-GMT3YPLT.js";
9
9
  export {
10
10
  createServer,
11
11
  loadConfig
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  IntelligenceService
3
- } from "./chunk-CXIGHPBE.js";
4
- import "./chunk-AVN6Q6LM.js";
3
+ } from "./chunk-UAQ42NVJ.js";
4
+ import "./chunk-GMT3YPLT.js";
5
5
  export {
6
6
  IntelligenceService
7
7
  };
package/dist/mcp.js CHANGED
@@ -3,8 +3,8 @@ import {
3
3
  PACKAGE_VERSION,
4
4
  canonryMcpTools,
5
5
  createApiClient
6
- } from "./chunk-2QBSRHSN.js";
7
- import "./chunk-AVN6Q6LM.js";
6
+ } from "./chunk-6XOZSS3Y.js";
7
+ import "./chunk-GMT3YPLT.js";
8
8
 
9
9
  // src/mcp/cli.ts
10
10
  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.80.0",
3
+ "version": "4.81.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",
@@ -62,24 +62,24 @@
62
62
  "@types/node-cron": "^3.0.11",
63
63
  "tsup": "^8.5.1",
64
64
  "tsx": "^4.19.0",
65
- "@ainyc/canonry-config": "0.0.0",
66
- "@ainyc/canonry-contracts": "0.0.0",
67
65
  "@ainyc/canonry-api-client": "0.0.0",
68
66
  "@ainyc/canonry-api-routes": "0.0.0",
69
- "@ainyc/canonry-integration-bing": "0.0.0",
67
+ "@ainyc/canonry-config": "0.0.0",
68
+ "@ainyc/canonry-contracts": "0.0.0",
70
69
  "@ainyc/canonry-db": "0.0.0",
70
+ "@ainyc/canonry-integration-bing": "0.0.0",
71
71
  "@ainyc/canonry-integration-openai-ads": "0.0.0",
72
- "@ainyc/canonry-integration-cloud-run": "0.0.0",
73
72
  "@ainyc/canonry-integration-commoncrawl": "0.0.0",
73
+ "@ainyc/canonry-integration-cloud-run": "0.0.0",
74
74
  "@ainyc/canonry-integration-google": "0.0.0",
75
75
  "@ainyc/canonry-integration-google-business-profile": "0.0.0",
76
- "@ainyc/canonry-integration-wordpress": "0.0.0",
77
- "@ainyc/canonry-intelligence": "0.0.0",
78
- "@ainyc/canonry-integration-google-places": "0.0.0",
79
76
  "@ainyc/canonry-integration-traffic": "0.0.0",
77
+ "@ainyc/canonry-integration-google-places": "0.0.0",
78
+ "@ainyc/canonry-integration-wordpress": "0.0.0",
80
79
  "@ainyc/canonry-provider-cdp": "0.0.0",
81
80
  "@ainyc/canonry-provider-claude": "0.0.0",
82
81
  "@ainyc/canonry-provider-gemini": "0.0.0",
82
+ "@ainyc/canonry-intelligence": "0.0.0",
83
83
  "@ainyc/canonry-provider-local": "0.0.0",
84
84
  "@ainyc/canonry-provider-openai": "0.0.0",
85
85
  "@ainyc/canonry-provider-perplexity": "0.0.0"