@canonry/canonry 7.77.2 → 7.78.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 (139) hide show
  1. package/assets/agent-workspace/skills/aero/references/seo-analysis.md +13 -2
  2. package/assets/agent-workspace/skills/canonry/references/canonry-cli.md +4 -2
  3. package/assets/assets/{AgentSetupPage-BZXWC3x6.js → AgentSetupPage-BGdvyQFL.js} +4 -4
  4. package/assets/assets/{AuditHistoryPanel-DcrUuwRu.js → AuditHistoryPanel-Bb5wq-Bk.js} +1 -1
  5. package/assets/assets/{BacklinksPage-BSpHJBiy.js → BacklinksPage-i1cfxTDj.js} +1 -1
  6. package/assets/assets/{HistoryPage-0a0CK9zF.js → HistoryPage-C2NRdNrn.js} +1 -1
  7. package/assets/assets/MeasurementPropertyPage-CwPuJMBy.js +4 -0
  8. package/assets/assets/ProjectPage-Bbnbg7c9.js +11 -0
  9. package/assets/assets/{RunsPage-D0vbz1Ho.js → RunsPage-CJHJ7kHk.js} +1 -1
  10. package/assets/assets/{SettingsPage-DjRm5cmn.js → SettingsPage-r8VrtFyJ.js} +1 -1
  11. package/assets/assets/SiteHealthSection-D1oSuo9O.js +2 -0
  12. package/assets/assets/ToneBadge-CUe-WrzN.js +60 -0
  13. package/assets/assets/{TrafficPage-Z8Z_z0k9.js → TrafficPage-DY2ykwH1.js} +1 -1
  14. package/assets/assets/TrafficSourceDetailPage-D3KHgRvF.js +1 -0
  15. package/assets/assets/{account-context-zaSxLBst.js → account-context-B50QqDEA.js} +1 -1
  16. package/assets/assets/{card-COqALGzB.js → card-BE2fqwVq.js} +1 -1
  17. package/assets/assets/{extract-error-message-DKve0SNr.js → extract-error-message-xuN_xeRJ.js} +1 -1
  18. package/assets/assets/{format-helpers-DKrHlaV7.js → format-helpers-CiC6gALY.js} +1 -1
  19. package/assets/assets/{index-CKZK95pI.css → index-CHHZDc6d.css} +1 -1
  20. package/assets/assets/{index-fzqtwr6m.js → index-Dfm8z5cG.js} +23 -23
  21. package/assets/assets/{query-client-COM9uzxL.js → query-client-C5GhDMY7.js} +1 -1
  22. package/assets/assets/react-query-CmHyfYFq.js +1 -0
  23. package/assets/assets/{react-sigma_core.esm.min-e91U3Myi.js → react-sigma_core.esm.min-Bjdtl0TQ.js} +1 -1
  24. package/assets/assets/{service-BgFTYqJA.js → service-B2i_ZzWP.js} +1 -1
  25. package/assets/index.html +8 -8
  26. package/dist/{ads-5K5IQDCD.js → ads-MIR5MCHL.js} +3 -3
  27. package/dist/{agent-Q4PKMBEJ.js → agent-IXRL5RBI.js} +7 -7
  28. package/dist/{agent-ask-JEPVVW2J.js → agent-ask-K42H6H2T.js} +3 -3
  29. package/dist/{agent-conversations-EHE7QEBC.js → agent-conversations-2T3W4DHO.js} +3 -3
  30. package/dist/{agent-memory-AB72YQET.js → agent-memory-LJBNSTSP.js} +3 -3
  31. package/dist/{agent-providers-NQ7HJYAQ.js → agent-providers-QR4LY3AP.js} +3 -3
  32. package/dist/{agent-transcript-PRTWIQ2A.js → agent-transcript-JIHJWHV6.js} +3 -3
  33. package/dist/{analytics-IY3J4VZE.js → analytics-JRV7DBBU.js} +3 -3
  34. package/dist/{apply-HNOG674K.js → apply-ZFWDSAV4.js} +3 -3
  35. package/dist/{backfill-TO7TPPO6.js → backfill-LU2AQIPY.js} +9 -9
  36. package/dist/{backlinks-3NY5GNT4.js → backlinks-NAC2373F.js} +3 -3
  37. package/dist/{bing-Z7W7U2CT.js → bing-L3LDBJOC.js} +3 -3
  38. package/dist/{bootstrap-DXXS3LRH.js → bootstrap-I6DA4KWB.js} +10 -10
  39. package/dist/{cdp-CKPRS6VE.js → cdp-4F74XLTH.js} +7 -7
  40. package/dist/{chunk-AAUMUHUI.js → chunk-367K6XVX.js} +2 -2
  41. package/dist/{chunk-JPOIDGGF.js → chunk-3MGM3U6V.js} +1 -1
  42. package/dist/{chunk-2BDWXHYF.js → chunk-45RGH7XI.js} +3 -3
  43. package/dist/{chunk-RPJJOBKN.js → chunk-6ACWXQNZ.js} +3 -1
  44. package/dist/{chunk-5LKK2MCJ.js → chunk-6P6YBNKN.js} +7 -7
  45. package/dist/{chunk-6KPBYCPE.js → chunk-6PRFVLIK.js} +2 -2
  46. package/dist/{chunk-D5XPB7MM.js → chunk-6VBLPCCX.js} +1 -1
  47. package/dist/{chunk-5QR7D4RQ.js → chunk-7HB6QLX4.js} +1 -1
  48. package/dist/{chunk-7UVCZZQJ.js → chunk-AI44ZCMK.js} +1 -1
  49. package/dist/{chunk-JRVKW4OO.js → chunk-C5WSQXP5.js} +26 -2
  50. package/dist/{chunk-CHTKK43G.js → chunk-EFMZSYRD.js} +149 -24
  51. package/dist/{chunk-CMS4YM5M.js → chunk-EHXNYXAS.js} +3 -3
  52. package/dist/{chunk-2WBT6TEJ.js → chunk-FCYGY4FT.js} +1 -1
  53. package/dist/{chunk-XYYWKCJQ.js → chunk-JERATA5R.js} +1 -1
  54. package/dist/{chunk-JMCURBZG.js → chunk-JEUL5QZP.js} +4 -4
  55. package/dist/{chunk-PSNTEGNY.js → chunk-KZB6HLFT.js} +1 -1
  56. package/dist/{chunk-4XVXP6VR.js → chunk-L2KMR7CM.js} +2 -2
  57. package/dist/{chunk-EM2HAM2U.js → chunk-L6F2HOQH.js} +8 -8
  58. package/dist/{chunk-GDKMVOZI.js → chunk-M3BUP6XD.js} +104 -13
  59. package/dist/{chunk-4QHTXT4A.js → chunk-MUYTDD35.js} +40 -4
  60. package/dist/{chunk-TESDUMVK.js → chunk-O4WBYEGV.js} +1 -1
  61. package/dist/{chunk-FCGYYZHL.js → chunk-PM2DB3HE.js} +164 -10
  62. package/dist/{chunk-JZ4UFSVR.js → chunk-QXSOXDUR.js} +2 -2
  63. package/dist/{chunk-LKEFPJQ2.js → chunk-RSVANBNW.js} +4 -4
  64. package/dist/{chunk-G26YB6JK.js → chunk-SAHH2FXO.js} +3 -3
  65. package/dist/{chunk-46KV7CZU.js → chunk-SOQVI7EZ.js} +2 -2
  66. package/dist/{chunk-Z2FY6AGZ.js → chunk-TZRYVW75.js} +2 -2
  67. package/dist/{chunk-C3UFOS7J.js → chunk-UH44UCRM.js} +2 -2
  68. package/dist/{chunk-JEXBP7CR.js → chunk-UQOC5ZQE.js} +4 -4
  69. package/dist/{chunk-7JC4Z6FQ.js → chunk-VLOCDWCS.js} +1 -1
  70. package/dist/{chunk-WFFZAQRG.js → chunk-WCFANFR2.js} +371 -340
  71. package/dist/{chunk-ZXYCPRNY.js → chunk-WSWHLKKJ.js} +1 -1
  72. package/dist/{chunk-NDTU7FGL.js → chunk-WVCDUKJ2.js} +1 -1
  73. package/dist/{chunk-ORZBHCZR.js → chunk-WXIL2EFM.js} +4 -4
  74. package/dist/{chunk-JSCO223C.js → chunk-ZHFE6J3A.js} +1 -1
  75. package/dist/{chunk-HD2VVIPD.js → chunk-ZUC7CJVD.js} +5 -5
  76. package/dist/{citations-4AV6HLUZ.js → citations-2XELMCCV.js} +3 -3
  77. package/dist/{cli-catalog-ZVFLJXID.js → cli-catalog-KC6JYHSW.js} +3 -3
  78. package/dist/{cli-commands-NJDUBQ3R.js → cli-commands-WCOAB6XU.js} +7 -7
  79. package/dist/cli.js +13 -13
  80. package/dist/{competitor-SG4N37UD.js → competitor-IK4GYTZO.js} +3 -3
  81. package/dist/{content-EDLZAPUV.js → content-SMQPJXPC.js} +3 -3
  82. package/dist/{dashboard-5ZFVJPHX.js → dashboard-EE24ROVG.js} +6 -6
  83. package/dist/{demo-5CU3JDHC.js → demo-7XH2N65A.js} +1 -1
  84. package/dist/{demo-server-43QV3UKM.js → demo-server-CVB65UYW.js} +12 -12
  85. package/dist/{discover-7X2WMNFV.js → discover-3KHUCVE7.js} +3 -3
  86. package/dist/{discover-eval-ECOPSJJ4.js → discover-eval-DOEP4ZQ7.js} +3 -3
  87. package/dist/{doctor-NMFBKNYR.js → doctor-3T6RKSE7.js} +3 -3
  88. package/dist/{evidence-C52ZPRYB.js → evidence-4NFL5KM3.js} +3 -3
  89. package/dist/{export-cmd-2WSEETUC.js → export-cmd-BQC6XLJ7.js} +3 -3
  90. package/dist/{ga-YG4O2FT5.js → ga-HBRA4UUK.js} +3 -3
  91. package/dist/{gbp-BDGV6F74.js → gbp-2WMBTDJV.js} +3 -3
  92. package/dist/{google-P2AX6CUF.js → google-JFUE4BNJ.js} +4 -4
  93. package/dist/{google-marketing-XPE6CVQI.js → google-marketing-5ROIKBC7.js} +1 -1
  94. package/dist/{health-cmd-MIQT2JNL.js → health-cmd-7BMVCCG2.js} +3 -3
  95. package/dist/{history-3XDDJDAV.js → history-QA4ZXCVH.js} +3 -3
  96. package/dist/index.d.ts +198 -6
  97. package/dist/index.js +26 -26
  98. package/dist/{init-GT3QM7FC.js → init-O4G2MDMC.js} +12 -12
  99. package/dist/{insights-ZJUDCBBP.js → insights-K4UX2PSI.js} +3 -3
  100. package/dist/intelligence-service-D7DS4UKT.js +16 -0
  101. package/dist/{journeys-L2CXQXRP.js → journeys-UWEWJXGT.js} +3 -3
  102. package/dist/{keys-ODRGIQS7.js → keys-CL5YYE7Q.js} +3 -3
  103. package/dist/{keyword-LE3CAXO2.js → keyword-IFCC5IZT.js} +3 -3
  104. package/dist/{logs-OXK43XN2.js → logs-2A3HBUBK.js} +3 -3
  105. package/dist/{mcp-6OTPCDGW.js → mcp-B6L7PKZ4.js} +4 -4
  106. package/dist/mcp.js +10 -10
  107. package/dist/{measurement-plan-NXRCDUYL.js → measurement-plan-GYSO6CXX.js} +5 -5
  108. package/dist/{notify-VNNJTNC6.js → notify-XM23I2B3.js} +3 -3
  109. package/dist/{organic-evidence-LYDB7IID.js → organic-evidence-U7HZMXKP.js} +3 -3
  110. package/dist/{overview-2GPPQ6JP.js → overview-TSAK5DQP.js} +4 -4
  111. package/dist/{project-CQJPXC66.js → project-L7DLDEPI.js} +3 -3
  112. package/dist/{query-PPE4EHMY.js → query-FM5HDHO4.js} +3 -3
  113. package/dist/{research-GDYZKQY2.js → research-7G5JU44N.js} +3 -3
  114. package/dist/{results-export-OAJHDEIQ.js → results-export-JJDGG6ZP.js} +3 -3
  115. package/dist/{run-XDPDQS44.js → run-ZVIQVG23.js} +4 -4
  116. package/dist/{schedule-C6SYV54I.js → schedule-TV7LWSYI.js} +3 -3
  117. package/dist/{search-DONTDHQK.js → search-7KRZLZ6S.js} +3 -3
  118. package/dist/{serve-PJXATOSY.js → serve-WSOG525W.js} +27 -27
  119. package/dist/{session-PMZV27GX.js → session-OUGQSGVV.js} +14 -14
  120. package/dist/{settings-PMATG7GG.js → settings-AOXQJOHN.js} +3 -3
  121. package/dist/{skills-CYHWYN42.js → skills-DWXA55QA.js} +2 -2
  122. package/dist/{snapshot-E4GHH6DD.js → snapshot-B44CXKFU.js} +3 -3
  123. package/dist/{src-SXB3MOP3.js → src-IBGSUYEG.js} +2 -2
  124. package/dist/{status-MEGXEEW6.js → status-RNBSFZ6Q.js} +4 -4
  125. package/dist/{technical-aeo-GE6KOFKT.js → technical-aeo-UAOKK5QH.js} +3 -3
  126. package/dist/{telemetry-Y63F4XFX.js → telemetry-55PUOMA7.js} +4 -4
  127. package/dist/{tools-V546ALG7.js → tools-HRGP4FXN.js} +11 -11
  128. package/dist/{traffic-5ELSKXBM.js → traffic-M4OHG5JW.js} +5 -5
  129. package/dist/{users-7YK7XYWY.js → users-GU7MULRM.js} +3 -3
  130. package/dist/{visibility-stats-GYPUKXVS.js → visibility-stats-4IDTDXDC.js} +3 -3
  131. package/dist/{wordpress-WUGJT5NN.js → wordpress-CYXB4R5Y.js} +3 -3
  132. package/package.json +1 -1
  133. package/assets/assets/MeasurementPropertyPage-DbfTFN3F.js +0 -4
  134. package/assets/assets/ProjectPage-D0m-Xpp3.js +0 -9
  135. package/assets/assets/SiteHealthSection-BCdPVFEJ.js +0 -2
  136. package/assets/assets/ToneBadge-DSJSzqI6.js +0 -60
  137. package/assets/assets/TrafficSourceDetailPage-DJyDO527.js +0 -1
  138. package/assets/assets/react-query-BVRWpXWq.js +0 -1
  139. package/dist/intelligence-service-NXZYQJBH.js +0 -16
@@ -3,7 +3,7 @@ import {
3
3
  resolveCliAccess,
4
4
  resolveCliAccessForInvocation,
5
5
  windowOptions
6
- } from "./chunk-RPJJOBKN.js";
6
+ } from "./chunk-6ACWXQNZ.js";
7
7
  import {
8
8
  emitJsonl
9
9
  } from "./chunk-Z7IUAJOF.js";
@@ -14,7 +14,7 @@ import {
14
14
  } from "./chunk-HGMYEDAQ.js";
15
15
  import {
16
16
  OperationAccesses
17
- } from "./chunk-FCGYYZHL.js";
17
+ } from "./chunk-PM2DB3HE.js";
18
18
 
19
19
  // src/cli-catalog.ts
20
20
  import { createRequire } from "module";
@@ -111,7 +111,7 @@ async function dispatchRegisteredCommand(args, fallbackFormat, specs) {
111
111
  const accessValue = accessFilterFromArgs(argsWithoutHelp);
112
112
  validateAccessFilter(accessValue);
113
113
  if (fallbackFormat !== "text") {
114
- const { printCliCatalog: printCliCatalog2 } = await import("./cli-catalog-ZVFLJXID.js");
114
+ const { printCliCatalog: printCliCatalog2 } = await import("./cli-catalog-KC6JYHSW.js");
115
115
  const group2 = argsWithoutHelp.find((arg) => !arg.startsWith("--"));
116
116
  printCliCatalog2(specs, fallbackFormat, group2, accessValue);
117
117
  return true;
@@ -5,7 +5,7 @@ import {
5
5
  AppError,
6
6
  parseWindowIn,
7
7
  resolveDateRange
8
- } from "./chunk-FCGYYZHL.js";
8
+ } from "./chunk-PM2DB3HE.js";
9
9
 
10
10
  // src/cli-access.ts
11
11
  var CLI_ACCESS_BY_ID = Object.freeze({
@@ -329,8 +329,10 @@ var CLI_ACCESS_BY_ID = Object.freeze({
329
329
  "sentiment.job": "stored",
330
330
  "sentiment.jobs": "stored",
331
331
  "sentiment.settings": "stored",
332
+ "seo.competitors": "stored",
332
333
  "seo.context": "stored",
333
334
  "seo.domain-intelligence": "stored",
335
+ "seo.keyword-gaps": "stored",
334
336
  "seo.keyword-metrics": "stored",
335
337
  "seo.market-rankings": "stored",
336
338
  "seo.market-summary": "stored",
@@ -5,10 +5,10 @@ import {
5
5
  isStoredPageReadTool,
6
6
  isStoredReadTool,
7
7
  truncateToolResult
8
- } from "./chunk-ORZBHCZR.js";
8
+ } from "./chunk-WXIL2EFM.js";
9
9
  import {
10
10
  CANONRY_MCP_TOOLKITS
11
- } from "./chunk-NDTU7FGL.js";
11
+ } from "./chunk-WVCDUKJ2.js";
12
12
  import {
13
13
  AGENT_REASONING_LEVELS,
14
14
  aeroStreamFn,
@@ -22,18 +22,18 @@ import {
22
22
  resolveApiKeyFor,
23
23
  resolveModelForProvider,
24
24
  validateAgentProviderRegistry
25
- } from "./chunk-7JC4Z6FQ.js";
25
+ } from "./chunk-VLOCDWCS.js";
26
26
  import {
27
27
  CanonryMcpToolNames,
28
28
  canonryMcpTools
29
- } from "./chunk-4QHTXT4A.js";
29
+ } from "./chunk-MUYTDD35.js";
30
30
  import {
31
31
  createLogger
32
- } from "./chunk-Z2FY6AGZ.js";
32
+ } from "./chunk-TZRYVW75.js";
33
33
  import {
34
34
  agentToolEvents,
35
35
  llmUsageEvents
36
- } from "./chunk-D5XPB7MM.js";
36
+ } from "./chunk-6VBLPCCX.js";
37
37
  import {
38
38
  MeasurementPortfolioLists,
39
39
  SeoCapabilities,
@@ -42,7 +42,7 @@ import {
42
42
  describeError,
43
43
  validationError,
44
44
  visibilityReportRequestSchema
45
- } from "./chunk-FCGYYZHL.js";
45
+ } from "./chunk-PM2DB3HE.js";
46
46
 
47
47
  // src/agent/session.ts
48
48
  import fs3 from "fs";
@@ -5,7 +5,7 @@ import {
5
5
  loadConfig,
6
6
  loadConfigRaw,
7
7
  saveConfigPatch
8
- } from "./chunk-7JC4Z6FQ.js";
8
+ } from "./chunk-VLOCDWCS.js";
9
9
  import {
10
10
  CANONRY_NPM_PACKAGE_URL,
11
11
  compareSemver,
@@ -18,7 +18,7 @@ import {
18
18
  updateCheckEnvOptOut,
19
19
  upgradeCaveatFor,
20
20
  upgradeCommandFor
21
- } from "./chunk-FCGYYZHL.js";
21
+ } from "./chunk-PM2DB3HE.js";
22
22
 
23
23
  // src/runtime-context.ts
24
24
  function cliRuntimeContext(env = process.env, stdio = process) {
@@ -20,7 +20,7 @@ import {
20
20
  templateLinkRatio,
21
21
  templateLinkUbiquityAvailable,
22
22
  validationError
23
- } from "./chunk-FCGYYZHL.js";
23
+ } from "./chunk-PM2DB3HE.js";
24
24
  import {
25
25
  __export
26
26
  } from "./chunk-MLKGABMK.js";
@@ -23,7 +23,7 @@ import {
23
23
  measurementDraftUpsertGroupRequestSchema,
24
24
  measurementDraftUpsertMarketRequestSchema,
25
25
  measurementDraftUpsertTargetRequestSchema
26
- } from "./chunk-FCGYYZHL.js";
26
+ } from "./chunk-PM2DB3HE.js";
27
27
 
28
28
  // src/measurement-draft-actions.ts
29
29
  import { z } from "zod";
@@ -15,7 +15,7 @@ import {
15
15
  formatCanonryPluginUpdateHint,
16
16
  formatCanonryPluginVersionMismatch,
17
17
  skillsClientSchema
18
- } from "./chunk-FCGYYZHL.js";
18
+ } from "./chunk-PM2DB3HE.js";
19
19
 
20
20
  // src/commands/skills.ts
21
21
  import crypto from "crypto";
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  loadConfig
3
- } from "./chunk-7JC4Z6FQ.js";
3
+ } from "./chunk-VLOCDWCS.js";
4
4
  import {
5
5
  PACKAGE_VERSION
6
6
  } from "./chunk-AOJU5LKX.js";
@@ -36,7 +36,7 @@ import {
36
36
  sentimentSettingsReadSchema,
37
37
  sentimentSummaryReadSchema,
38
38
  upgradeCommandFor
39
- } from "./chunk-FCGYYZHL.js";
39
+ } from "./chunk-PM2DB3HE.js";
40
40
 
41
41
  // ../api-client-generated/src/generated/core/bodySerializer.gen.ts
42
42
  var jsonBodySerializer = {
@@ -900,6 +900,16 @@ var getApiV1ProjectsByNameSeoRankedKeywords = (options) => (options.client ?? cl
900
900
  url: "/api/v1/projects/{name}/seo/ranked-keywords",
901
901
  ...options
902
902
  });
903
+ var getApiV1ProjectsByNameSeoCompetitors = (options) => (options.client ?? client).get({
904
+ security: [{ scheme: "bearer", type: "http" }],
905
+ url: "/api/v1/projects/{name}/seo/competitors",
906
+ ...options
907
+ });
908
+ var getApiV1ProjectsByNameSeoKeywordGaps = (options) => (options.client ?? client).get({
909
+ security: [{ scheme: "bearer", type: "http" }],
910
+ url: "/api/v1/projects/{name}/seo/keyword-gaps",
911
+ ...options
912
+ });
903
913
  var getApiV1ProjectsByNameSeoMarketRankings = (options) => (options.client ?? client).get({
904
914
  security: [{ scheme: "bearer", type: "http" }],
905
915
  url: "/api/v1/projects/{name}/seo/market-rankings",
@@ -6220,6 +6230,20 @@ var ApiClient = class {
6220
6230
  query
6221
6231
  }));
6222
6232
  }
6233
+ async getSeoCompetitors(project, query) {
6234
+ return this.invoke(() => getApiV1ProjectsByNameSeoCompetitors({
6235
+ client: this.heyClient,
6236
+ path: { name: project },
6237
+ query
6238
+ }));
6239
+ }
6240
+ async getSeoKeywordGaps(project, query) {
6241
+ return this.invoke(() => getApiV1ProjectsByNameSeoKeywordGaps({
6242
+ client: this.heyClient,
6243
+ path: { name: project },
6244
+ query
6245
+ }));
6246
+ }
6223
6247
  async getSeoMarketRankings(project, query) {
6224
6248
  return this.invoke(() => getApiV1ProjectsByNameSeoMarketRankings({
6225
6249
  client: this.heyClient,
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  answerServiceAdapters,
3
3
  answerServiceDescriptors
4
- } from "./chunk-ZXYCPRNY.js";
4
+ } from "./chunk-WSWHLKKJ.js";
5
5
  import {
6
6
  AeroLlmUsageFeatures,
7
7
  aeroTurnStatus,
@@ -27,14 +27,14 @@ import {
27
27
  resolveConfiguredAgentProvider,
28
28
  resolveSessionProviderAndModel,
29
29
  setAeroSystemPrompt
30
- } from "./chunk-5LKK2MCJ.js";
30
+ } from "./chunk-6P6YBNKN.js";
31
31
  import {
32
32
  AeroToolProfiles,
33
33
  AeroToolScopes,
34
34
  buildAeroStateTools,
35
35
  isAeroToolProfile,
36
36
  truncateToolResult
37
- } from "./chunk-ORZBHCZR.js";
37
+ } from "./chunk-WXIL2EFM.js";
38
38
  import {
39
39
  getGoogleAuthConfig,
40
40
  getGoogleConnection,
@@ -53,7 +53,7 @@ import {
53
53
  removeCloudflareTrafficConnection,
54
54
  removeCloudflareTrafficConnectionBySourceId,
55
55
  upsertCloudflareTrafficConnection
56
- } from "./chunk-PSNTEGNY.js";
56
+ } from "./chunk-KZB6HLFT.js";
57
57
  import {
58
58
  claudeAdapter,
59
59
  embedQueries,
@@ -64,7 +64,7 @@ import {
64
64
  openaiAdapter,
65
65
  openrouterAdapter,
66
66
  perplexityAdapter
67
- } from "./chunk-C3UFOS7J.js";
67
+ } from "./chunk-UH44UCRM.js";
68
68
  import {
69
69
  classifyUsageSurface,
70
70
  createApiUsageTelemetry,
@@ -76,7 +76,7 @@ import {
76
76
  startOutcomeTimer,
77
77
  trackFeatureCompleted,
78
78
  trackInstallState
79
- } from "./chunk-JEXBP7CR.js";
79
+ } from "./chunk-UQOC5ZQE.js";
80
80
  import {
81
81
  isLoopbackBindHost
82
82
  } from "./chunk-TSENU4GG.js";
@@ -84,7 +84,7 @@ import {
84
84
  isApiProviderRegistrable,
85
85
  isCdpProviderRegistrable,
86
86
  registeredProviderNames
87
- } from "./chunk-2WBT6TEJ.js";
87
+ } from "./chunk-FCYGY4FT.js";
88
88
  import {
89
89
  checkLatestVersionForServer,
90
90
  getOrCreateAnonymousId,
@@ -96,17 +96,17 @@ import {
96
96
  recordDashboardEvent,
97
97
  setTelemetryPreference,
98
98
  trackEvent
99
- } from "./chunk-6KPBYCPE.js";
99
+ } from "./chunk-6PRFVLIK.js";
100
100
  import {
101
101
  createCanonryMcpServer
102
- } from "./chunk-LKEFPJQ2.js";
102
+ } from "./chunk-RSVANBNW.js";
103
103
  import {
104
104
  CANONRY_MCP_TIERS,
105
105
  CANONRY_MCP_TOOLKIT_NAMES
106
- } from "./chunk-NDTU7FGL.js";
106
+ } from "./chunk-WVCDUKJ2.js";
107
107
  import {
108
108
  ApiClient
109
- } from "./chunk-JRVKW4OO.js";
109
+ } from "./chunk-C5WSQXP5.js";
110
110
  import {
111
111
  AGENT_PROVIDERS,
112
112
  adapterSupportsBatch,
@@ -138,21 +138,21 @@ import {
138
138
  saveConfigPatch,
139
139
  sentimentInstallReadiness,
140
140
  updateSharedProviderExecutionGate
141
- } from "./chunk-7JC4Z6FQ.js";
141
+ } from "./chunk-VLOCDWCS.js";
142
142
  import {
143
143
  getBundledSkillSnapshots
144
- } from "./chunk-7UVCZZQJ.js";
144
+ } from "./chunk-AI44ZCMK.js";
145
145
  import {
146
146
  computeFactorAverages,
147
147
  deleteSiteCrawlGraphLayout,
148
148
  persistSiteCrawlGraphLayout,
149
149
  prepareSiteCrawlGraphLayout,
150
150
  recordedSharePct
151
- } from "./chunk-46KV7CZU.js";
151
+ } from "./chunk-SOQVI7EZ.js";
152
152
  import {
153
153
  CanonryMcpToolNames,
154
154
  canonryMcpTools
155
- } from "./chunk-4QHTXT4A.js";
155
+ } from "./chunk-MUYTDD35.js";
156
156
  import {
157
157
  PACKAGE_VERSION
158
158
  } from "./chunk-AOJU5LKX.js";
@@ -161,16 +161,16 @@ import {
161
161
  } from "./chunk-HGMYEDAQ.js";
162
162
  import {
163
163
  IntelligenceService
164
- } from "./chunk-HD2VVIPD.js";
164
+ } from "./chunk-ZUC7CJVD.js";
165
165
  import {
166
166
  addLogListener,
167
167
  createFastifyLogger,
168
168
  createLogger
169
- } from "./chunk-Z2FY6AGZ.js";
169
+ } from "./chunk-TZRYVW75.js";
170
170
  import {
171
171
  computeCitedCompetitorDomains,
172
172
  determineCitationState
173
- } from "./chunk-XYYWKCJQ.js";
173
+ } from "./chunk-JERATA5R.js";
174
174
  import {
175
175
  BingApiError,
176
176
  CC_CACHE_DIR,
@@ -291,7 +291,7 @@ import {
291
291
  webhookResponseReason,
292
292
  webhookTargetRefusalReason,
293
293
  writeAuditLog
294
- } from "./chunk-GDKMVOZI.js";
294
+ } from "./chunk-M3BUP6XD.js";
295
295
  import {
296
296
  OperationalLogStore,
297
297
  SentimentIdempotencyConflict,
@@ -377,7 +377,7 @@ import {
377
377
  siteLivenessState,
378
378
  trafficSources,
379
379
  usageCounters
380
- } from "./chunk-D5XPB7MM.js";
380
+ } from "./chunk-6VBLPCCX.js";
381
381
  import {
382
382
  AGENT_MEMORY_VALUE_MAX_BYTES,
383
383
  AI_ENGINE_DOMAINS,
@@ -457,6 +457,7 @@ import {
457
457
  SentimentOutcomes,
458
458
  SeoAdapterOutcomes,
459
459
  SeoCapabilities,
460
+ SeoKeywordGapModes,
460
461
  SeoMarketRankingSearchStatuses,
461
462
  SeoProviders,
462
463
  SeoRunStatuses,
@@ -576,6 +577,7 @@ import {
576
577
  normalizeIdTokens,
577
578
  normalizeMeasurementExecutionQueryText,
578
579
  normalizeProjectDomain,
580
+ normalizeQueryText,
579
581
  normalizeServedModel,
580
582
  normalizeSiteAuditRunRequest,
581
583
  normalizeUrlPath,
@@ -606,6 +608,8 @@ import {
606
608
  sentimentEvaluatorProvider,
607
609
  sentimentSelectionSchema,
608
610
  seoDeviceSchema,
611
+ seoKeywordGapComparison,
612
+ seoKeywordGapModeSchema,
609
613
  seoProfileInputSchema,
610
614
  seoRankingSettingsSchema,
611
615
  serializeForInlineScript,
@@ -629,7 +633,7 @@ import {
629
633
  winnabilityClassLabel,
630
634
  withRetry,
631
635
  withSkippedProviders
632
- } from "./chunk-FCGYYZHL.js";
636
+ } from "./chunk-PM2DB3HE.js";
633
637
 
634
638
  // src/google-marketing-runtime.ts
635
639
  import crypto2 from "crypto";
@@ -3459,8 +3463,27 @@ var resultSchema = z2.object({
3459
3463
  location_code: z2.number().int(),
3460
3464
  language_code: z2.string(),
3461
3465
  target: z2.string().optional(),
3466
+ target1: z2.string().optional(),
3467
+ target2: z2.string().optional(),
3462
3468
  items: z2.array(z2.unknown()).nullable()
3463
3469
  });
3470
+ var competitorItemSchema = z2.object({
3471
+ domain: z2.string(),
3472
+ intersections: count,
3473
+ avg_position: amount,
3474
+ full_domain_metrics: z2.object({ organic: z2.object({ count, etv: amount }).nullish() }).nullish()
3475
+ });
3476
+ var comparisonSerpSchema = z2.object({
3477
+ type: z2.literal("organic"),
3478
+ domain: z2.string(),
3479
+ url: z2.string().nullish(),
3480
+ rank_group: z2.number().int().positive()
3481
+ });
3482
+ var gapItemSchema = z2.object({
3483
+ keyword_data: keywordDataSchema,
3484
+ first_domain_serp_element: comparisonSerpSchema,
3485
+ second_domain_serp_element: comparisonSerpSchema.nullish()
3486
+ });
3464
3487
  var serpResultSchema = z2.object({
3465
3488
  keyword: z2.string(),
3466
3489
  location_code: z2.number().int(),
@@ -3570,11 +3593,75 @@ function normalizeDataForSeoResults(rawResults, request, collectedAt, options =
3570
3593
  throw new Error("SEO provider returned a different market.");
3571
3594
  }
3572
3595
  const providerTarget = request.target?.kind === SeoTargetKinds.host ? registrableDomain(request.target.value) : request.target?.value.toLowerCase();
3573
- if (request.target && result.target?.toLowerCase() !== providerTarget) {
3596
+ if (request.capability === SeoCapabilities["keyword-gaps"]) {
3597
+ if (result.target1?.toLowerCase() !== request.comparison?.competitor.value.toLowerCase() || result.target2?.toLowerCase() !== providerTarget) {
3598
+ throw new Error("SEO provider returned a different comparison pair.");
3599
+ }
3600
+ } else if (request.target && result.target?.toLowerCase() !== providerTarget) {
3574
3601
  throw new Error("SEO provider returned a different target.");
3575
3602
  }
3576
3603
  const items = result.items ?? [];
3577
3604
  switch (request.capability) {
3605
+ case SeoCapabilities["competitor-discovery"]: {
3606
+ if (!request.target) throw new Error("SEO target is required.");
3607
+ const seen = /* @__PURE__ */ new Set();
3608
+ for (const rawItem of items) {
3609
+ const item = competitorItemSchema.parse(rawItem);
3610
+ const domain = normalizeHostname(item.domain);
3611
+ if (!domain || !registrableDomain(domain)) throw new Error("SEO provider returned an invalid competitor domain.");
3612
+ if (registrableDomain(domain) === request.target.value.toLowerCase() || seen.has(domain)) continue;
3613
+ seen.add(domain);
3614
+ output.competitors.push({
3615
+ target: request.target,
3616
+ domain,
3617
+ sharedKeywords: item.intersections ?? null,
3618
+ averagePosition: item.avg_position ?? null,
3619
+ organicKeywords: item.full_domain_metrics?.organic?.count ?? null,
3620
+ estimatedOrganicTraffic: item.full_domain_metrics?.organic?.etv ?? null,
3621
+ // The endpoint does not return its weekly dataset timestamp.
3622
+ provenance: provenance(request, collectedAt, null)
3623
+ });
3624
+ }
3625
+ break;
3626
+ }
3627
+ case SeoCapabilities["keyword-gaps"]: {
3628
+ if (!request.target || !request.comparison) throw new Error("SEO comparison is required.");
3629
+ const { competitor, mode } = request.comparison;
3630
+ const seen = /* @__PURE__ */ new Set();
3631
+ for (const rawItem of items) {
3632
+ const item = gapItemSchema.parse(rawItem);
3633
+ const rival = item.first_domain_serp_element;
3634
+ const own = item.second_domain_serp_element;
3635
+ const rivalHost = normalizeHostname(rival.domain);
3636
+ const ownHost = own ? normalizeHostname(own.domain) : null;
3637
+ if (!rivalHost || !hostBelongsTo(rivalHost, competitor) || own && (!ownHost || !hostBelongsTo(ownHost, request.target))) {
3638
+ throw new Error("SEO provider returned rankings outside the comparison pair.");
3639
+ }
3640
+ if (mode === SeoKeywordGapModes.shared && !own || mode === SeoKeywordGapModes.missing && own) {
3641
+ throw new Error("SEO provider returned a different comparison population.");
3642
+ }
3643
+ const key = normalizeQueryText(item.keyword_data.keyword);
3644
+ if (seen.has(key)) continue;
3645
+ seen.add(key);
3646
+ const metric = keywordMetrics(item.keyword_data, request, collectedAt);
3647
+ const targetRankOrganic = own?.rank_group ?? null;
3648
+ output.keywordGaps.push({
3649
+ target: request.target,
3650
+ competitor,
3651
+ keyword: metric.keyword,
3652
+ targetRankOrganic,
3653
+ competitorRankOrganic: rival.rank_group,
3654
+ targetUrl: own?.url ?? null,
3655
+ competitorUrl: rival.url ?? null,
3656
+ searchVolume: metric.searchVolume,
3657
+ keywordDifficulty: metric.keywordDifficulty,
3658
+ cpcUsd: metric.cpcUsd,
3659
+ ...seoKeywordGapComparison(targetRankOrganic, rival.rank_group),
3660
+ provenance: provenance(request, collectedAt, item.keyword_data.serp_info?.last_updated_time ?? null)
3661
+ });
3662
+ }
3663
+ break;
3664
+ }
3578
3665
  case SeoCapabilities["keyword-metrics"]: {
3579
3666
  const requested = new Map(request.keywords.map((keyword) => [keyword.toLowerCase(), keyword]));
3580
3667
  for (const rawItem of items) {
@@ -3643,7 +3730,9 @@ var ENDPOINTS = {
3643
3730
  [SeoCapabilities["keyword-metrics"]]: "dataforseo_labs/google/keyword_overview/live",
3644
3731
  [SeoCapabilities["domain-intelligence"]]: "dataforseo_labs/google/domain_rank_overview/live",
3645
3732
  [SeoCapabilities["ranked-keywords"]]: "dataforseo_labs/google/ranked_keywords/live",
3646
- [SeoCapabilities["market-rankings"]]: "serp/google/organic/live/advanced"
3733
+ [SeoCapabilities["market-rankings"]]: "serp/google/organic/live/advanced",
3734
+ [SeoCapabilities["competitor-discovery"]]: "dataforseo_labs/google/competitors_domain/live",
3735
+ [SeoCapabilities["keyword-gaps"]]: "dataforseo_labs/google/domain_intersection/live"
3647
3736
  };
3648
3737
  var MAX_SEARCH_TEXT_LENGTH = 700;
3649
3738
  var SURCHARGED_OPERATORS = [
@@ -3734,6 +3823,40 @@ function taskPayload(request) {
3734
3823
  const host = targetHost(target);
3735
3824
  const domain = registrableDomain(host);
3736
3825
  switch (request.capability) {
3826
+ case SeoCapabilities["competitor-discovery"]:
3827
+ if (target.kind !== SeoTargetKinds.domain) throw validationError("Competitor discovery requires a whole-domain scope.");
3828
+ return {
3829
+ ...common,
3830
+ target: host,
3831
+ limit: request.limit,
3832
+ offset: 0,
3833
+ item_types: ["organic"],
3834
+ include_clickstream_data: false,
3835
+ ignore_synonyms: false,
3836
+ exclude_domains: [host],
3837
+ order_by: ["intersections,desc"]
3838
+ };
3839
+ case SeoCapabilities["keyword-gaps"]: {
3840
+ const comparison = request.comparison;
3841
+ if (target.kind !== SeoTargetKinds.domain || !comparison || comparison.competitor.kind !== SeoTargetKinds.domain) {
3842
+ throw validationError("Keyword gaps require a whole-domain target and comparison domain.");
3843
+ }
3844
+ if (!seoKeywordGapModeSchema.safeParse(comparison.mode).success) throw validationError("Choose shared or missing searches for keyword gaps.");
3845
+ const competitor = targetHost(comparison.competitor);
3846
+ if (competitor === host) throw validationError("Choose a comparison domain different from the target.");
3847
+ return {
3848
+ ...common,
3849
+ target1: competitor,
3850
+ target2: host,
3851
+ intersections: comparison.mode === SeoKeywordGapModes.shared,
3852
+ limit: request.limit,
3853
+ offset: 0,
3854
+ item_types: ["organic"],
3855
+ include_serp_info: true,
3856
+ include_clickstream_data: false,
3857
+ order_by: ["keyword_data.keyword_info.search_volume,desc"]
3858
+ };
3859
+ }
3737
3860
  case SeoCapabilities["domain-intelligence"]:
3738
3861
  if (target.kind !== SeoTargetKinds.domain) throw validationError("Domain intelligence requires a whole-domain scope.");
3739
3862
  return { ...common, target: host, limit: 1, ignore_synonyms: false };
@@ -3768,6 +3891,8 @@ function appendResults(target, source) {
3768
3891
  target.domainIntelligence.push(...source.domainIntelligence);
3769
3892
  target.rankedKeywords.push(...source.rankedKeywords);
3770
3893
  target.marketRankings.push(...source.marketRankings);
3894
+ target.competitors.push(...source.competitors);
3895
+ target.keywordGaps.push(...source.keywordGaps);
3771
3896
  }
3772
3897
  function createDataForSeoAdapter(credentials) {
3773
3898
  const auth = { login: credentials.login.trim(), password: credentials.password };
@@ -5812,7 +5937,7 @@ function nonBlank(value) {
5812
5937
  return trimmed ? trimmed : void 0;
5813
5938
  }
5814
5939
  function resolveBuildCommit(env = process.env) {
5815
- const embedded = true ? "31abb805953cc5f5c6cfa83e68610c6944e35b6c" : void 0;
5940
+ const embedded = true ? "d072bd75fd700d80034392e01808c70cb509c189" : void 0;
5816
5941
  return nonBlank(embedded) ?? nonBlank(env.CANONRY_COMMIT);
5817
5942
  }
5818
5943
  function resolveInstanceIdentity(env = process.env) {
@@ -2,18 +2,18 @@ import {
2
2
  configExists,
3
3
  loadConfigRaw,
4
4
  saveConfigPatch
5
- } from "./chunk-7JC4Z6FQ.js";
5
+ } from "./chunk-VLOCDWCS.js";
6
6
  import {
7
7
  BUNDLED_SKILL_NAMES,
8
8
  installSkills
9
- } from "./chunk-7UVCZZQJ.js";
9
+ } from "./chunk-AI44ZCMK.js";
10
10
  import {
11
11
  PACKAGE_VERSION
12
12
  } from "./chunk-AOJU5LKX.js";
13
13
  import {
14
14
  SKILL_MANIFEST_FILENAME,
15
15
  SkillsClients
16
- } from "./chunk-FCGYYZHL.js";
16
+ } from "./chunk-PM2DB3HE.js";
17
17
 
18
18
  // src/skills-autosync.ts
19
19
  import fs from "fs";
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  API_PROVIDER_NAMES,
3
3
  ProviderNames
4
- } from "./chunk-FCGYYZHL.js";
4
+ } from "./chunk-PM2DB3HE.js";
5
5
 
6
6
  // src/provider-registration.ts
7
7
  function isApiProviderRegistrable(name, entry) {
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  hostMatchesDomain
3
- } from "./chunk-FCGYYZHL.js";
3
+ } from "./chunk-PM2DB3HE.js";
4
4
 
5
5
  // src/citation-utils.ts
6
6
  function pickProjectCitedDomain(citedDomains, projectDomains) {
@@ -1,10 +1,10 @@
1
1
  import {
2
2
  registeredProviderNames
3
- } from "./chunk-2WBT6TEJ.js";
3
+ } from "./chunk-FCYGY4FT.js";
4
4
  import {
5
5
  configExists,
6
6
  loadConfigRaw
7
- } from "./chunk-7JC4Z6FQ.js";
7
+ } from "./chunk-VLOCDWCS.js";
8
8
 
9
9
  // src/setup-state.ts
10
10
  import fs from "fs";
@@ -28,7 +28,7 @@ async function buildSetupState() {
28
28
  }
29
29
  if (dbPath && fs.existsSync(dbPath)) {
30
30
  try {
31
- const { createClient, projects, queries: queriesTable } = await import("./src-SXB3MOP3.js");
31
+ const { createClient, projects, queries: queriesTable } = await import("./src-IBGSUYEG.js");
32
32
  const db = createClient(dbPath);
33
33
  project_count = db.select({ id: projects.id }).from(projects).all().length;
34
34
  const firstQuery = db.select({ id: queriesTable.id }).from(queriesTable).limit(1).all();
@@ -47,7 +47,7 @@ function queueServeHandoff() {
47
47
  async function runPendingServeHandoff(format) {
48
48
  if (!pendingServeHandoff) return;
49
49
  pendingServeHandoff = false;
50
- const { serveCommand } = await import("./serve-PJXATOSY.js");
50
+ const { serveCommand } = await import("./serve-WSOG525W.js");
51
51
  await serveCommand(format);
52
52
  }
53
53
 
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  cloudflareQueueNameSchema
3
- } from "./chunk-FCGYYZHL.js";
3
+ } from "./chunk-PM2DB3HE.js";
4
4
 
5
5
  // src/cloudflare-traffic-config.ts
6
6
  function unsupportedDeliveryMode(deliveryMode) {
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  createApiClient
3
- } from "./chunk-JRVKW4OO.js";
3
+ } from "./chunk-C5WSQXP5.js";
4
4
  import {
5
5
  emitJsonl
6
6
  } from "./chunk-Z7IUAJOF.js";
@@ -19,7 +19,7 @@ import {
19
19
  formatMicros,
20
20
  formatRunErrorOneLine,
21
21
  resolveProviderInput
22
- } from "./chunk-FCGYYZHL.js";
22
+ } from "./chunk-PM2DB3HE.js";
23
23
 
24
24
  // src/commands/run.ts
25
25
  function getClient() {