@canonry/canonry 4.136.0 → 4.136.2

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 (30) hide show
  1. package/assets/agent-workspace/skills/canonry/references/canonry-cli.md +4 -0
  2. package/assets/agent-workspace/skills/canonry/references/indexing.md +26 -12
  3. package/assets/assets/{AuditHistoryPanel-DKaiIlcO.js → AuditHistoryPanel-DtUGiN21.js} +1 -1
  4. package/assets/assets/{BacklinksPage-Z2_ws8c2.js → BacklinksPage-BGwtmwfz.js} +1 -1
  5. package/assets/assets/{ChartPrimitives-CF_ocuvj.js → ChartPrimitives-Df2UC1g3.js} +1 -1
  6. package/assets/assets/{HistoryPage-DDKO8_D8.js → HistoryPage-AtaMVEUx.js} +1 -1
  7. package/assets/assets/ProjectPage-OlBjxXNx.js +8 -0
  8. package/assets/assets/{RunRow-BhtCgyqA.js → RunRow-Cmf-5xVo.js} +1 -1
  9. package/assets/assets/{RunsPage-B8Nw3wP-.js → RunsPage-BAPy9Yri.js} +1 -1
  10. package/assets/assets/{SettingsPage-DsmQhytl.js → SettingsPage-BXO7WpTo.js} +1 -1
  11. package/assets/assets/{TrafficPage-COJs6eRH.js → TrafficPage-IH-wiPu2.js} +1 -1
  12. package/assets/assets/{TrafficSourceDetailPage-BI6IwzMQ.js → TrafficSourceDetailPage-CTTN-P52.js} +1 -1
  13. package/assets/assets/{arrow-left-C-lGPq-u.js → arrow-left-BwzAIeJ_.js} +1 -1
  14. package/assets/assets/{extract-error-message-8h0hF1I1.js → extract-error-message-BIcIoJLN.js} +1 -1
  15. package/assets/assets/index-BPpSrJY0.js +210 -0
  16. package/assets/assets/index-CglduHCN.css +1 -0
  17. package/assets/assets/{trash-2-CnOZwYKe.js → trash-2-C50OeBAV.js} +1 -1
  18. package/assets/index.html +2 -2
  19. package/dist/{chunk-PXEEWJRV.js → chunk-GGIRLRAY.js} +3093 -399
  20. package/dist/{chunk-3PFRVEWP.js → chunk-MXR3GI5L.js} +54 -122
  21. package/dist/{chunk-PAR6P5H6.js → chunk-SMFUCXHI.js} +132 -6
  22. package/dist/{chunk-TPVMHYHD.js → chunk-YVMQWVNY.js} +291 -206
  23. package/dist/cli.js +184 -15
  24. package/dist/index.js +4 -4
  25. package/dist/{intelligence-service-BMEJ5GFZ.js → intelligence-service-BD6BHTEJ.js} +2 -2
  26. package/dist/mcp.js +2 -2
  27. package/package.json +9 -9
  28. package/assets/assets/ProjectPage-hmNsqBov.js +0 -8
  29. package/assets/assets/index-B4ksyQXo.css +0 -1
  30. package/assets/assets/index-BoSfFv1t.js +0 -210
package/dist/cli.js CHANGED
@@ -29,7 +29,7 @@ import {
29
29
  setTelemetrySource,
30
30
  showFirstRunNotice,
31
31
  trackEvent
32
- } from "./chunk-3PFRVEWP.js";
32
+ } from "./chunk-MXR3GI5L.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-PAR6P5H6.js";
49
+ } from "./chunk-SMFUCXHI.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-TPVMHYHD.js";
57
+ } from "./chunk-YVMQWVNY.js";
58
58
  import {
59
59
  AdsDeliverySnapshotStatuses,
60
60
  AdsHistoricalCampaignRollupStatuses,
@@ -100,7 +100,7 @@ import {
100
100
  providerQuotaPolicySchema,
101
101
  resolveProviderInput,
102
102
  winnabilityClassSchema
103
- } from "./chunk-PXEEWJRV.js";
103
+ } from "./chunk-GGIRLRAY.js";
104
104
 
105
105
  // src/cli.ts
106
106
  import { pathToFileURL } from "url";
@@ -6201,7 +6201,7 @@ var COMPETITOR_CLI_COMMANDS = [
6201
6201
  ];
6202
6202
 
6203
6203
  // src/commands/google.ts
6204
- 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.";
6204
+ var INDEXING_API_SCOPE_NOTICE = "Note: Google's Indexing API officially supports only pages with JobPosting or BroadcastEvent (livestream VideoObject) structured data. Other URL types are outside the supported use of that API. For general pages, submit a sitemap and use URL Inspection to monitor status.";
6205
6205
  function getClient11() {
6206
6206
  return createApiClient();
6207
6207
  }
@@ -6560,19 +6560,157 @@ async function googleListSitemaps(project, opts) {
6560
6560
  return;
6561
6561
  }
6562
6562
  if (result.sitemaps.length === 0) {
6563
- console.log(`No sitemaps found for project "${project}". Submit a sitemap in Google Search Console first.`);
6563
+ console.log(
6564
+ `No sitemaps found for project "${project}". Run "canonry google submit-sitemap ${project} <url>" to submit one.`
6565
+ );
6564
6566
  return;
6565
6567
  }
6566
6568
  console.log(`
6567
6569
  Sitemaps for project "${project}":
6568
6570
  `);
6569
6571
  for (const s of result.sitemaps) {
6570
- const indexed = s.contents?.[0]?.indexed ?? "?";
6571
- const submitted = s.contents?.[0]?.submitted ?? "?";
6572
+ const submitted = sitemapSubmittedUrlTotal(s.contents);
6572
6573
  const isIndex = s.isSitemapsIndex ? " [index]" : "";
6573
6574
  console.log(` ${s.path}${isIndex}`);
6574
- console.log(` Indexed: ${indexed} / ${submitted} submitted | Last submitted: ${s.lastSubmitted ?? "unknown"}`);
6575
+ console.log(` Submitted URLs: ${submitted} | Last submitted: ${s.lastSubmitted ?? "unknown"}`);
6576
+ }
6577
+ }
6578
+ function sitemapSubmittedUrlTotal(contents) {
6579
+ if (!contents?.length) return "?";
6580
+ return contents.reduce((total, content) => total + (Number.parseInt(content.submitted, 10) || 0), 0);
6581
+ }
6582
+ function dedupeSitemapUrls(urls) {
6583
+ return [...new Set(urls.map((url) => url.trim()).filter(Boolean))];
6584
+ }
6585
+ async function submitGscSitemaps(client, project, opts) {
6586
+ const explicitUrls = dedupeSitemapUrls(opts.sitemapUrls ?? []);
6587
+ const modes = Number(explicitUrls.length > 0) + Number(Boolean(opts.configured)) + Number(Boolean(opts.all)) + Number(Boolean(opts.allFiles));
6588
+ if (modes !== 1) {
6589
+ throw new CliError({
6590
+ code: "CLI_USAGE_ERROR",
6591
+ message: "provide sitemap URL(s), --configured, --all, or --all-files (exactly one)",
6592
+ displayMessage: "Error: provide sitemap URL(s), --configured, --all, or --all-files (exactly one)",
6593
+ details: { command: "google.submit-sitemap" }
6594
+ });
6595
+ }
6596
+ if (explicitUrls.length > 50) {
6597
+ throw new CliError({
6598
+ code: "CLI_USAGE_ERROR",
6599
+ message: "explicit sitemap URL submissions support at most 50 URLs; split the URLs into groups of 50 or use --all/--all-files for discovered sitemaps",
6600
+ displayMessage: "Error: explicit sitemap URL submissions support at most 50 URLs; split the URLs into groups of 50 or use --all/--all-files for discovered sitemaps",
6601
+ details: { command: "google.submit-sitemap", sitemapUrls: explicitUrls.length, maxSitemapUrls: 50 }
6602
+ });
6603
+ }
6604
+ let sitemapUrls = explicitUrls;
6605
+ if (opts.configured) {
6606
+ const connections = await client.googleConnections(project);
6607
+ const sitemapUrl = connections.find((connection) => connection.connectionType === "gsc")?.sitemapUrl;
6608
+ if (!sitemapUrl || !sitemapUrl.trim()) {
6609
+ throw new CliError({
6610
+ code: "CLI_USAGE_ERROR",
6611
+ message: "no configured GSC sitemap URL found; use a URL, --all, or --all-files",
6612
+ displayMessage: "Error: no configured GSC sitemap URL found; use a URL, --all, or --all-files",
6613
+ details: { command: "google.submit-sitemap", project }
6614
+ });
6615
+ }
6616
+ sitemapUrls = dedupeSitemapUrls([sitemapUrl]);
6617
+ } else if (opts.all || opts.allFiles) {
6618
+ const topLevel = await client.gscSitemaps(project);
6619
+ if (opts.all) {
6620
+ sitemapUrls = dedupeSitemapUrls(
6621
+ topLevel.preferredSubmissionUrls.length > 0 ? topLevel.preferredSubmissionUrls : topLevel.sitemaps.map((sitemap) => sitemap.path)
6622
+ );
6623
+ } else if (opts.allFiles) {
6624
+ const indexes = topLevel.sitemaps.filter((sitemap) => sitemap.isSitemapsIndex).map((sitemap) => sitemap.path);
6625
+ const children = [];
6626
+ for (let offset = 0; offset < indexes.length; offset += 4) {
6627
+ children.push(...await Promise.all(
6628
+ indexes.slice(offset, offset + 4).map((sitemapIndex) => client.gscSitemaps(project, { sitemapIndex }))
6629
+ ));
6630
+ }
6631
+ const expandedIndexUrls = children.flatMap(
6632
+ (result, index) => result.sitemaps.length > 0 ? result.sitemaps.map((sitemap) => sitemap.path) : [indexes[index]]
6633
+ );
6634
+ sitemapUrls = dedupeSitemapUrls([
6635
+ ...topLevel.sitemaps.filter((sitemap) => !sitemap.isSitemapsIndex).map((sitemap) => sitemap.path),
6636
+ ...expandedIndexUrls
6637
+ ]);
6638
+ }
6639
+ if (sitemapUrls.length === 0) {
6640
+ throw new CliError({
6641
+ code: "CLI_USAGE_ERROR",
6642
+ message: "no GSC sitemaps found; provide a URL or use --configured",
6643
+ displayMessage: "Error: no GSC sitemaps found; provide a URL or use --configured",
6644
+ details: { command: "google.submit-sitemap", project }
6645
+ });
6646
+ }
6647
+ }
6648
+ const batches = opts.all || opts.allFiles ? Array.from({ length: Math.ceil(sitemapUrls.length / 50) }, (_, index) => sitemapUrls.slice(index * 50, index * 50 + 50)) : [sitemapUrls];
6649
+ const aggregate = {
6650
+ summary: { total: 0, accepted: 0, failed: 0 },
6651
+ results: []
6652
+ };
6653
+ for (const [index, batchSitemapUrls] of batches.entries()) {
6654
+ try {
6655
+ const result = await client.gscSubmitSitemaps(project, { sitemapUrls: batchSitemapUrls });
6656
+ aggregate.summary.total += result.summary.total;
6657
+ aggregate.summary.accepted += result.summary.accepted;
6658
+ aggregate.summary.failed += result.summary.failed;
6659
+ aggregate.results.push(...result.results);
6660
+ opts.onProgress?.(index + 1, batches.length);
6661
+ } catch (cause) {
6662
+ if (index === 0) throw cause;
6663
+ const attempted = aggregate.summary.total + batchSitemapUrls.length;
6664
+ const remaining = sitemapUrls.length - attempted;
6665
+ const causeDetails = cause instanceof CliError ? { code: cause.code, message: cause.message, details: cause.details } : { message: cause instanceof Error ? cause.message : String(cause) };
6666
+ throw new CliError({
6667
+ code: "GOOGLE_SITEMAP_SUBMISSION_PARTIAL",
6668
+ message: `Sitemap submission stopped at batch ${index + 1}/${batches.length}; ${aggregate.summary.accepted} accepted, ${aggregate.summary.failed} failed, ${batchSitemapUrls.length} unconfirmed, ${remaining} not attempted.`,
6669
+ displayMessage: `Sitemap submission stopped at batch ${index + 1}/${batches.length}; ${aggregate.summary.accepted} accepted, ${aggregate.summary.failed} failed, ${batchSitemapUrls.length} unconfirmed, ${remaining} not attempted. Earlier accepted submissions were not rolled back.`,
6670
+ exitCode: cause instanceof CliError && cause.exitCode === 1 ? 1 : EXIT_SYSTEM_ERROR,
6671
+ details: {
6672
+ project,
6673
+ accepted: aggregate.summary.accepted,
6674
+ failed: aggregate.summary.failed,
6675
+ completed: aggregate.summary.total,
6676
+ attempted,
6677
+ unconfirmed: batchSitemapUrls.length,
6678
+ remaining,
6679
+ unconfirmedBatch: { index: index + 1, total: batches.length, sitemapUrls: batchSitemapUrls },
6680
+ partialResult: aggregate,
6681
+ cause: causeDetails
6682
+ }
6683
+ });
6684
+ }
6685
+ }
6686
+ return aggregate;
6687
+ }
6688
+ async function googleSubmitSitemaps(project, opts) {
6689
+ const client = getClient11();
6690
+ const result = await submitGscSitemaps(client, project, {
6691
+ ...opts,
6692
+ onProgress: !isMachineFormat(opts.format) && (opts.all || opts.allFiles) ? (completedBatches, totalBatches) => process.stderr.write(`Submitted sitemap batch ${completedBatches}/${totalBatches}
6693
+ `) : void 0
6694
+ });
6695
+ if (opts.format === "json") {
6696
+ console.log(JSON.stringify(result, null, 2));
6697
+ return;
6698
+ }
6699
+ if (opts.format === "jsonl") {
6700
+ emitJsonl(result.results.map((entry) => ({ project, ...entry })));
6701
+ return;
6702
+ }
6703
+ for (const entry of result.results) {
6704
+ if (entry.status === "accepted") {
6705
+ console.log(`Accepted by Google for sitemap refetch: ${entry.sitemapUrl}`);
6706
+ if (entry.submittedAt) console.log(` Submitted at: ${entry.submittedAt}`);
6707
+ } else {
6708
+ console.error(`Failed to submit sitemap: ${entry.sitemapUrl}`);
6709
+ if (entry.error) console.error(` Error: ${entry.error}`);
6710
+ }
6575
6711
  }
6712
+ console.log(`Summary: ${result.summary.accepted} accepted, ${result.summary.failed} failed (${result.summary.total} total)`);
6713
+ console.log("Google accepting a sitemap for refetch does not guarantee indexing.");
6576
6714
  }
6577
6715
  async function googleInspectSitemap(project, opts) {
6578
6716
  const client = getClient11();
@@ -6648,10 +6786,9 @@ Discovered ${result.sitemaps.length} sitemap(s) for project "${project}":
6648
6786
  `);
6649
6787
  for (const s of result.sitemaps) {
6650
6788
  const primary = s.path === result.primarySitemapUrl ? " (primary)" : "";
6651
- const indexed = s.contents?.[0]?.indexed ?? "?";
6652
- const submitted = s.contents?.[0]?.submitted ?? "?";
6789
+ const submitted = sitemapSubmittedUrlTotal(s.contents);
6653
6790
  console.log(` ${s.path}${primary}`);
6654
- console.log(` Indexed: ${indexed} / ${submitted} submitted | Last submitted: ${s.lastSubmitted ?? "unknown"}`);
6791
+ console.log(` Submitted URLs: ${submitted} | Last submitted: ${s.lastSubmitted ?? "unknown"}`);
6655
6792
  }
6656
6793
  console.log(`
6657
6794
  Primary sitemap: ${result.primarySitemapUrl}`);
@@ -6910,6 +7047,38 @@ var GOOGLE_CLI_COMMANDS = [
6910
7047
  await googleListSitemaps(project, { format: input.format });
6911
7048
  }
6912
7049
  },
7050
+ {
7051
+ path: ["google", "submit-sitemap"],
7052
+ usage: "canonry google submit-sitemap <project> [url...] [--configured|--all|--all-files] [--format json|jsonl]",
7053
+ options: {
7054
+ configured: { type: "boolean", default: false },
7055
+ all: { type: "boolean", default: false },
7056
+ "all-files": { type: "boolean", default: false }
7057
+ },
7058
+ run: async (input) => {
7059
+ const project = requireProject(input, "google.submit-sitemap", "canonry google submit-sitemap <project> [url...] [--configured|--all|--all-files] [--format json|jsonl]");
7060
+ const sitemapUrls = input.positionals.slice(1);
7061
+ const configured = getBoolean(input.values, "configured");
7062
+ const all = getBoolean(input.values, "all");
7063
+ const allFiles = getBoolean(input.values, "all-files");
7064
+ if (Number(sitemapUrls.length > 0) + Number(configured) + Number(all) + Number(allFiles) !== 1) {
7065
+ throw usageError("Error: provide sitemap URL(s), --configured, --all, or --all-files (exactly one)", {
7066
+ message: "provide sitemap URL(s), --configured, --all, or --all-files (exactly one)",
7067
+ details: {
7068
+ command: "google.submit-sitemap",
7069
+ usage: "canonry google submit-sitemap <project> [url...] [--configured|--all|--all-files] [--format json|jsonl]"
7070
+ }
7071
+ });
7072
+ }
7073
+ await googleSubmitSitemaps(project, {
7074
+ sitemapUrls,
7075
+ configured,
7076
+ all,
7077
+ allFiles,
7078
+ format: input.format
7079
+ });
7080
+ }
7081
+ },
6913
7082
  {
6914
7083
  path: ["google", "sync"],
6915
7084
  usage: "canonry google sync <project> [--type gsc|ga4] [--days <n>] [--full] [--wait] [--format json]",
@@ -7103,12 +7272,12 @@ var GOOGLE_CLI_COMMANDS = [
7103
7272
  },
7104
7273
  {
7105
7274
  path: ["google"],
7106
- usage: "canonry google <connect|disconnect|status|properties|set-property|set-sitemap|list-sitemaps|discover-sitemaps|sync|performance|performance-daily|inspect|inspect-sitemap|coverage|coverage-history|inspections|deindexed|request-indexing|refresh> <project> [args]",
7275
+ usage: "canonry google <connect|disconnect|status|properties|set-property|set-sitemap|list-sitemaps|submit-sitemap|discover-sitemaps|sync|performance|performance-daily|inspect|inspect-sitemap|coverage|coverage-history|inspections|deindexed|request-indexing|refresh> <project> [args]",
7107
7276
  run: async (input) => {
7108
7277
  unknownSubcommand(input.positionals[0], {
7109
7278
  command: "google",
7110
- usage: "canonry google <connect|disconnect|status|properties|set-property|set-sitemap|list-sitemaps|discover-sitemaps|sync|performance|performance-daily|inspect|inspect-sitemap|coverage|coverage-history|inspections|deindexed|request-indexing|refresh> <project> [args]",
7111
- available: ["connect", "disconnect", "status", "properties", "set-property", "set-sitemap", "list-sitemaps", "discover-sitemaps", "sync", "performance", "performance-daily", "inspect", "inspect-sitemap", "coverage", "coverage-history", "inspections", "deindexed", "request-indexing", "refresh"]
7279
+ usage: "canonry google <connect|disconnect|status|properties|set-property|set-sitemap|list-sitemaps|submit-sitemap|discover-sitemaps|sync|performance|performance-daily|inspect|inspect-sitemap|coverage|coverage-history|inspections|deindexed|request-indexing|refresh> <project> [args]",
7280
+ available: ["connect", "disconnect", "status", "properties", "set-property", "set-sitemap", "list-sitemaps", "submit-sitemap", "discover-sitemaps", "sync", "performance", "performance-daily", "inspect", "inspect-sitemap", "coverage", "coverage-history", "inspections", "deindexed", "request-indexing", "refresh"]
7112
7281
  });
7113
7282
  }
7114
7283
  }
package/dist/index.js CHANGED
@@ -1,11 +1,11 @@
1
1
  import {
2
2
  createServer
3
- } from "./chunk-3PFRVEWP.js";
3
+ } from "./chunk-MXR3GI5L.js";
4
4
  import {
5
5
  loadConfig
6
- } from "./chunk-PAR6P5H6.js";
7
- import "./chunk-TPVMHYHD.js";
8
- import "./chunk-PXEEWJRV.js";
6
+ } from "./chunk-SMFUCXHI.js";
7
+ import "./chunk-YVMQWVNY.js";
8
+ import "./chunk-GGIRLRAY.js";
9
9
  export {
10
10
  createServer,
11
11
  loadConfig
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  IntelligenceService
3
- } from "./chunk-TPVMHYHD.js";
4
- import "./chunk-PXEEWJRV.js";
3
+ } from "./chunk-YVMQWVNY.js";
4
+ import "./chunk-GGIRLRAY.js";
5
5
  export {
6
6
  IntelligenceService
7
7
  };
package/dist/mcp.js CHANGED
@@ -3,10 +3,10 @@ import {
3
3
  PACKAGE_VERSION,
4
4
  canonryMcpTools,
5
5
  createApiClient
6
- } from "./chunk-PAR6P5H6.js";
6
+ } from "./chunk-SMFUCXHI.js";
7
7
  import {
8
8
  isReadOnlyKey
9
- } from "./chunk-PXEEWJRV.js";
9
+ } from "./chunk-GGIRLRAY.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": "@canonry/canonry",
3
- "version": "4.136.0",
3
+ "version": "4.136.2",
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,25 +66,25 @@
66
66
  "tsup": "^8.5.1",
67
67
  "tsx": "^4.19.0",
68
68
  "@ainyc/canonry-api-client": "0.0.0",
69
- "@ainyc/canonry-config": "0.0.0",
70
69
  "@ainyc/canonry-api-routes": "0.0.0",
70
+ "@ainyc/canonry-config": "0.0.0",
71
71
  "@ainyc/canonry-contracts": "0.0.0",
72
72
  "@ainyc/canonry-db": "0.0.0",
73
73
  "@ainyc/canonry-integration-bing": "0.0.0",
74
- "@ainyc/canonry-integration-openai-ads": "0.0.0",
75
74
  "@ainyc/canonry-integration-cloud-run": "0.0.0",
75
+ "@ainyc/canonry-integration-openai-ads": "0.0.0",
76
76
  "@ainyc/canonry-integration-commoncrawl": "0.0.0",
77
+ "@ainyc/canonry-integration-google-places": "0.0.0",
77
78
  "@ainyc/canonry-integration-google-business-profile": "0.0.0",
78
- "@ainyc/canonry-integration-traffic": "0.0.0",
79
- "@ainyc/canonry-integration-wordpress": "0.0.0",
80
79
  "@ainyc/canonry-integration-google": "0.0.0",
81
- "@ainyc/canonry-intelligence": "0.0.0",
80
+ "@ainyc/canonry-integration-traffic": "0.0.0",
82
81
  "@ainyc/canonry-provider-cdp": "0.0.0",
83
- "@ainyc/canonry-integration-google-places": "0.0.0",
82
+ "@ainyc/canonry-integration-wordpress": "0.0.0",
84
83
  "@ainyc/canonry-provider-claude": "0.0.0",
85
- "@ainyc/canonry-provider-local": "0.0.0",
86
- "@ainyc/canonry-provider-gemini": "0.0.0",
84
+ "@ainyc/canonry-intelligence": "0.0.0",
87
85
  "@ainyc/canonry-provider-openai": "0.0.0",
86
+ "@ainyc/canonry-provider-gemini": "0.0.0",
87
+ "@ainyc/canonry-provider-local": "0.0.0",
88
88
  "@ainyc/canonry-provider-perplexity": "0.0.0"
89
89
  },
90
90
  "scripts": {