@ainyc/canonry 4.47.0 → 4.51.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 (34) hide show
  1. package/assets/agent-workspace/skills/aero/SKILL.md +11 -0
  2. package/assets/agent-workspace/skills/aero/references/orchestration.md +8 -0
  3. package/assets/agent-workspace/skills/aero/soul.md +1 -1
  4. package/assets/agent-workspace/skills/canonry/SKILL.md +2 -0
  5. package/assets/agent-workspace/skills/canonry/references/canonry-cli.md +14 -1
  6. package/assets/assets/BacklinksPage-DIZCcqsP.js +1 -0
  7. package/assets/assets/ChartPrimitives-9Kx3gzQL.js +1 -0
  8. package/assets/assets/ProjectPage-R2cxJb5Y.js +6 -0
  9. package/assets/assets/RunRow-DqezNIUy.js +1 -0
  10. package/assets/assets/RunsPage-CfvTJ9Ny.js +1 -0
  11. package/assets/assets/SettingsPage-HfMGIa5v.js +1 -0
  12. package/assets/assets/TrafficPage-DV_Dvpl3.js +1 -0
  13. package/assets/assets/TrafficSourceDetailPage-lefreKBO.js +1 -0
  14. package/assets/assets/arrow-left-DpxpMUNt.js +1 -0
  15. package/assets/assets/index-DKBPD33e.js +210 -0
  16. package/assets/assets/{index-BDMNXVHa.css → index-DeGyEwik.css} +1 -1
  17. package/assets/assets/server-traffic-Bm8iKtXK.js +1 -0
  18. package/assets/assets/trash-2-CnBiLbiZ.js +1 -0
  19. package/assets/assets/vendor-markdown-DK7fbRNb.js +14 -0
  20. package/assets/assets/vendor-radix-B57xfQbP.js +45 -0
  21. package/assets/assets/vendor-recharts-DWvKDyBF.js +36 -0
  22. package/assets/assets/vendor-tanstack-Dq7p98wZ.js +1 -0
  23. package/assets/index.html +6 -2
  24. package/dist/{chunk-4WXY57ET.js → chunk-2ARCCG5E.js} +1652 -753
  25. package/dist/{chunk-M7MSNUNQ.js → chunk-DLDLDWH4.js} +142 -44
  26. package/dist/{chunk-WYBKCDUH.js → chunk-FDR3G6SB.js} +2780 -2018
  27. package/dist/chunk-GGXU5VKI.js +5778 -0
  28. package/dist/cli.js +17 -8
  29. package/dist/index.js +4 -4
  30. package/dist/{intelligence-service-ADZRFCGO.js → intelligence-service-XMZEWLCW.js} +2 -2
  31. package/dist/mcp.js +2 -2
  32. package/package.json +7 -6
  33. package/assets/assets/index-CPUAzk7n.js +0 -302
  34. package/dist/chunk-ON545FBK.js +0 -2369
@@ -57,7 +57,7 @@ var PROVIDER_LOCATION_HANDLING = {
57
57
  },
58
58
  openai: {
59
59
  treatment: "request-param",
60
- description: "Location sent as a structured `user_location` field on OpenAI\u2019s web_search_preview tool."
60
+ description: "Location sent as a structured `user_location` field on OpenAI\u2019s web_search tool."
61
61
  },
62
62
  claude: {
63
63
  treatment: "request-param",
@@ -93,7 +93,7 @@ var runKindSchema = z2.enum([
93
93
  "aeo-discover-probe"
94
94
  ]);
95
95
  var RunKinds = runKindSchema.enum;
96
- var runTriggerSchema = z2.enum(["manual", "scheduled", "config-apply", "backfill"]);
96
+ var runTriggerSchema = z2.enum(["manual", "scheduled", "config-apply", "backfill", "probe"]);
97
97
  var RunTriggers = runTriggerSchema.enum;
98
98
  var citationStateSchema = z2.enum(["cited", "not-cited"]);
99
99
  var CitationStates = citationStateSchema.enum;
@@ -105,9 +105,10 @@ var computedTransitionSchema = z2.enum(["new", "cited", "lost", "emerging", "not
105
105
  var ComputedTransitions = computedTransitionSchema.enum;
106
106
  var mentionTransitionSchema = z2.enum(["new", "mentioned", "lost", "emerging", "not-mentioned"]);
107
107
  var MentionTransitions = mentionTransitionSchema.enum;
108
+ var operatorTriggerSchema = z2.enum([RunTriggers.manual, RunTriggers.probe]);
108
109
  var runTriggerRequestSchema = z2.object({
109
110
  kind: z2.literal(RunKinds["answer-visibility"]).optional(),
110
- trigger: z2.literal(RunTriggers.manual).optional(),
111
+ trigger: operatorTriggerSchema.optional(),
111
112
  providers: z2.array(providerNameSchema).optional(),
112
113
  queries: z2.array(z2.string().min(1)).min(1).optional(),
113
114
  location: z2.string().min(1).optional(),
@@ -444,6 +445,13 @@ var projectDtoSchema = z4.object({
444
445
  language: z4.string().min(2),
445
446
  tags: z4.array(z4.string()).default([]),
446
447
  labels: z4.record(z4.string(), z4.string()).default({}),
448
+ // Provider names this project sweeps against (subset of available providers).
449
+ // The server emits this on every project response (see GET /projects/:name in
450
+ // packages/api-routes/src/projects.ts) — the schema was historically missing
451
+ // the field even though the wire shape always included it. Add it here so
452
+ // ProjectDto consumers (web + CLI ApiClient) typecheck against the real
453
+ // response surface.
454
+ providers: z4.array(z4.string()).default([]),
447
455
  locations: z4.array(locationContextSchema).default([]),
448
456
  defaultLocation: z4.string().nullable().optional(),
449
457
  autoExtractBacklinks: z4.boolean().default(false),
@@ -722,6 +730,12 @@ var gscUrlInspectionDtoSchema = z6.object({
722
730
  lastCrawlResult: z6.string().nullable().optional(),
723
731
  isMobileFriendly: z6.boolean().nullable().optional(),
724
732
  richResults: z6.array(z6.string()).default([]),
733
+ // Spec gap: server has returned `referringUrls` since the GSC inspect
734
+ // route shipped (see google.ts handler at /gsc/inspect + /gsc/inspections),
735
+ // but the schema dropped the field so the generated TS client (and
736
+ // anything else reading from this DTO) lost the data silently. Adding
737
+ // here restores end-to-end visibility.
738
+ referringUrls: z6.array(z6.string()).default([]),
725
739
  inspectedAt: z6.string()
726
740
  });
727
741
  var indexTransitionSchema = z6.enum(["stable", "reindexed", "deindexed", "still-missing", "new"]);
@@ -763,12 +777,46 @@ var indexingRequestResultDtoSchema = z6.object({
763
777
  status: z6.enum(["success", "error"]),
764
778
  error: z6.string().optional()
765
779
  });
780
+ var indexingRequestResponseDtoSchema = z6.object({
781
+ summary: z6.object({
782
+ total: z6.number().int().nonnegative(),
783
+ succeeded: z6.number().int().nonnegative(),
784
+ failed: z6.number().int().nonnegative()
785
+ }),
786
+ results: z6.array(indexingRequestResultDtoSchema).default([])
787
+ });
766
788
  var gscCoverageSnapshotDtoSchema = z6.object({
767
789
  date: z6.string(),
768
790
  indexed: z6.number(),
769
791
  notIndexed: z6.number(),
770
792
  reasonBreakdown: z6.record(z6.string(), z6.number()).default({})
771
793
  });
794
+ var gscSiteDtoSchema = z6.object({
795
+ siteUrl: z6.string(),
796
+ permissionLevel: z6.string()
797
+ });
798
+ var gscSiteListResponseDtoSchema = z6.object({
799
+ sites: z6.array(gscSiteDtoSchema).default([])
800
+ });
801
+ var gscSitemapContentDtoSchema = z6.object({
802
+ type: z6.string(),
803
+ submitted: z6.string(),
804
+ indexed: z6.string()
805
+ });
806
+ var gscSitemapDtoSchema = z6.object({
807
+ path: z6.string(),
808
+ lastSubmitted: z6.string().optional(),
809
+ isPending: z6.boolean().optional(),
810
+ isSitemapsIndex: z6.boolean().optional(),
811
+ type: z6.string().optional(),
812
+ lastDownloaded: z6.string().optional(),
813
+ warnings: z6.string().optional(),
814
+ errors: z6.string().optional(),
815
+ contents: z6.array(gscSitemapContentDtoSchema).optional()
816
+ });
817
+ var gscSitemapListResponseDtoSchema = z6.object({
818
+ sitemaps: z6.array(gscSitemapDtoSchema).default([])
819
+ });
772
820
 
773
821
  // ../contracts/src/bing.ts
774
822
  import { z as z7 } from "zod";
@@ -824,152 +872,198 @@ var bingSubmitResultDtoSchema = z7.object({
824
872
  submittedAt: z7.string(),
825
873
  error: z7.string().optional()
826
874
  });
875
+ var bingIndexingRequestResponseDtoSchema = z7.object({
876
+ summary: z7.object({
877
+ total: z7.number().int().nonnegative(),
878
+ succeeded: z7.number().int().nonnegative(),
879
+ failed: z7.number().int().nonnegative()
880
+ }),
881
+ results: z7.array(bingSubmitResultDtoSchema).default([])
882
+ });
883
+ var bingSiteDtoSchema = z7.object({
884
+ url: z7.string(),
885
+ verified: z7.boolean()
886
+ });
887
+ var bingSitesResponseDtoSchema = z7.object({
888
+ sites: z7.array(bingSiteDtoSchema).default([])
889
+ });
890
+ var bingStatusDtoSchema = z7.object({
891
+ connected: z7.boolean(),
892
+ domain: z7.string(),
893
+ siteUrl: z7.string().nullable(),
894
+ createdAt: z7.string().nullable(),
895
+ updatedAt: z7.string().nullable()
896
+ });
897
+ var bingConnectResponseDtoSchema = z7.object({
898
+ connected: z7.boolean(),
899
+ domain: z7.string(),
900
+ siteUrl: z7.string().nullable(),
901
+ availableSites: z7.array(bingSiteDtoSchema).default([])
902
+ });
903
+ var bingSetSiteResponseDtoSchema = z7.object({
904
+ siteUrl: z7.string()
905
+ });
827
906
 
828
- // ../contracts/src/wordpress.ts
907
+ // ../contracts/src/cdp.ts
829
908
  import { z as z8 } from "zod";
830
- var wordpressEnvSchema = z8.enum(["live", "staging"]);
831
- var wordpressConnectionDtoSchema = z8.object({
832
- projectName: z8.string(),
833
- url: z8.string(),
834
- stagingUrl: z8.string().optional(),
835
- username: z8.string(),
909
+ var cdpTargetStatusDtoSchema = z8.object({
910
+ name: z8.string(),
911
+ alive: z8.boolean(),
912
+ lastUsed: z8.string().nullable()
913
+ });
914
+ var cdpStatusDtoSchema = z8.object({
915
+ connected: z8.boolean(),
916
+ endpoint: z8.string(),
917
+ version: z8.string().optional(),
918
+ browserVersion: z8.string().optional(),
919
+ targets: z8.array(cdpTargetStatusDtoSchema).default([])
920
+ });
921
+
922
+ // ../contracts/src/wordpress.ts
923
+ import { z as z9 } from "zod";
924
+ var wordpressEnvSchema = z9.enum(["live", "staging"]);
925
+ var wordpressConnectionDtoSchema = z9.object({
926
+ projectName: z9.string(),
927
+ url: z9.string(),
928
+ stagingUrl: z9.string().optional(),
929
+ username: z9.string(),
836
930
  defaultEnv: wordpressEnvSchema,
837
- createdAt: z8.string(),
838
- updatedAt: z8.string()
839
- });
840
- var wordpressSiteStatusDtoSchema = z8.object({
841
- url: z8.string(),
842
- reachable: z8.boolean(),
843
- pageCount: z8.number().nullable().optional(),
844
- version: z8.string().nullable().optional(),
845
- error: z8.string().nullable().optional(),
846
- plugins: z8.array(z8.string()).optional(),
847
- authenticatedUser: z8.object({
848
- id: z8.number(),
849
- slug: z8.string()
931
+ createdAt: z9.string(),
932
+ updatedAt: z9.string()
933
+ });
934
+ var wordpressSiteStatusDtoSchema = z9.object({
935
+ url: z9.string(),
936
+ reachable: z9.boolean(),
937
+ pageCount: z9.number().nullable().optional(),
938
+ version: z9.string().nullable().optional(),
939
+ error: z9.string().nullable().optional(),
940
+ plugins: z9.array(z9.string()).optional(),
941
+ authenticatedUser: z9.object({
942
+ id: z9.number(),
943
+ slug: z9.string()
850
944
  }).nullable().optional()
851
945
  });
852
- var wordpressStatusDtoSchema = z8.object({
853
- connected: z8.boolean(),
854
- projectName: z8.string(),
946
+ var wordpressStatusDtoSchema = z9.object({
947
+ connected: z9.boolean(),
948
+ projectName: z9.string(),
855
949
  defaultEnv: wordpressEnvSchema,
856
950
  live: wordpressSiteStatusDtoSchema.nullable(),
857
951
  staging: wordpressSiteStatusDtoSchema.nullable(),
858
- adminUrl: z8.string().nullable().optional()
859
- });
860
- var wordpressPageSummaryDtoSchema = z8.object({
861
- id: z8.number(),
862
- slug: z8.string(),
863
- title: z8.string(),
864
- status: z8.string(),
865
- modifiedAt: z8.string().nullable().optional(),
866
- link: z8.string().nullable().optional()
867
- });
868
- var wordpressSeoStateDtoSchema = z8.object({
869
- title: z8.string().nullable(),
870
- description: z8.string().nullable(),
871
- noindex: z8.boolean().nullable(),
872
- writable: z8.boolean().default(false),
873
- writeTargets: z8.array(z8.string()).default([])
874
- });
875
- var wordpressSchemaBlockDtoSchema = z8.object({
876
- type: z8.string(),
877
- json: z8.record(z8.string(), z8.unknown())
952
+ adminUrl: z9.string().nullable().optional()
953
+ });
954
+ var wordpressPageSummaryDtoSchema = z9.object({
955
+ id: z9.number(),
956
+ slug: z9.string(),
957
+ title: z9.string(),
958
+ status: z9.string(),
959
+ modifiedAt: z9.string().nullable().optional(),
960
+ link: z9.string().nullable().optional()
961
+ });
962
+ var wordpressSeoStateDtoSchema = z9.object({
963
+ title: z9.string().nullable(),
964
+ description: z9.string().nullable(),
965
+ noindex: z9.boolean().nullable(),
966
+ writable: z9.boolean().default(false),
967
+ writeTargets: z9.array(z9.string()).default([])
968
+ });
969
+ var wordpressSchemaBlockDtoSchema = z9.object({
970
+ type: z9.string(),
971
+ json: z9.record(z9.string(), z9.unknown())
878
972
  });
879
973
  var wordpressPageDetailDtoSchema = wordpressPageSummaryDtoSchema.extend({
880
974
  env: wordpressEnvSchema,
881
- content: z8.string(),
975
+ content: z9.string(),
882
976
  seo: wordpressSeoStateDtoSchema,
883
- schemaBlocks: z8.array(wordpressSchemaBlockDtoSchema).default([])
977
+ schemaBlocks: z9.array(wordpressSchemaBlockDtoSchema).default([])
884
978
  });
885
979
  var wordpressDiffPageDtoSchema = wordpressPageDetailDtoSchema.extend({
886
- contentHash: z8.string(),
887
- contentSnippet: z8.string()
888
- });
889
- var wordpressManualAssistDtoSchema = z8.object({
890
- manualRequired: z8.literal(true),
891
- targetUrl: z8.string(),
892
- adminUrl: z8.string().nullable().optional(),
893
- content: z8.string(),
894
- nextSteps: z8.array(z8.string()).default([])
895
- });
896
- var wordpressAuditIssueDtoSchema = z8.object({
897
- slug: z8.string(),
898
- severity: z8.enum(["high", "medium", "low"]),
899
- code: z8.enum([
980
+ contentHash: z9.string(),
981
+ contentSnippet: z9.string()
982
+ });
983
+ var wordpressManualAssistDtoSchema = z9.object({
984
+ manualRequired: z9.literal(true),
985
+ targetUrl: z9.string(),
986
+ adminUrl: z9.string().nullable().optional(),
987
+ content: z9.string(),
988
+ nextSteps: z9.array(z9.string()).default([])
989
+ });
990
+ var wordpressAuditIssueDtoSchema = z9.object({
991
+ slug: z9.string(),
992
+ severity: z9.enum(["high", "medium", "low"]),
993
+ code: z9.enum([
900
994
  "noindex",
901
995
  "missing-seo-title",
902
996
  "missing-meta-description",
903
997
  "missing-schema",
904
998
  "thin-content"
905
999
  ]),
906
- message: z8.string()
1000
+ message: z9.string()
907
1001
  });
908
- var wordpressAuditPageDtoSchema = z8.object({
909
- slug: z8.string(),
910
- title: z8.string(),
911
- status: z8.string(),
912
- wordCount: z8.number(),
1002
+ var wordpressAuditPageDtoSchema = z9.object({
1003
+ slug: z9.string(),
1004
+ title: z9.string(),
1005
+ status: z9.string(),
1006
+ wordCount: z9.number(),
913
1007
  seo: wordpressSeoStateDtoSchema,
914
- schemaPresent: z8.boolean(),
915
- issues: z8.array(wordpressAuditIssueDtoSchema).default([])
1008
+ schemaPresent: z9.boolean(),
1009
+ issues: z9.array(wordpressAuditIssueDtoSchema).default([])
916
1010
  });
917
- var wordpressBulkMetaEntryResultDtoSchema = z8.object({
918
- slug: z8.string(),
919
- status: z8.enum(["applied", "skipped", "manual"]),
920
- error: z8.string().optional(),
1011
+ var wordpressBulkMetaEntryResultDtoSchema = z9.object({
1012
+ slug: z9.string(),
1013
+ status: z9.enum(["applied", "skipped", "manual"]),
1014
+ error: z9.string().optional(),
921
1015
  manualAssist: wordpressManualAssistDtoSchema.optional()
922
1016
  });
923
- var wordpressBulkMetaResultDtoSchema = z8.object({
1017
+ var wordpressBulkMetaResultDtoSchema = z9.object({
924
1018
  env: wordpressEnvSchema,
925
- strategy: z8.enum(["plugin", "manual"]),
926
- results: z8.array(wordpressBulkMetaEntryResultDtoSchema)
1019
+ strategy: z9.enum(["plugin", "manual"]),
1020
+ results: z9.array(wordpressBulkMetaEntryResultDtoSchema)
927
1021
  });
928
- var wordpressSchemaDeployEntryResultDtoSchema = z8.object({
929
- slug: z8.string(),
930
- status: z8.enum(["deployed", "stripped", "skipped", "failed"]),
931
- schemasInjected: z8.array(z8.string()).optional(),
1022
+ var wordpressSchemaDeployEntryResultDtoSchema = z9.object({
1023
+ slug: z9.string(),
1024
+ status: z9.enum(["deployed", "stripped", "skipped", "failed"]),
1025
+ schemasInjected: z9.array(z9.string()).optional(),
932
1026
  manualAssist: wordpressManualAssistDtoSchema.optional(),
933
- error: z8.string().optional()
1027
+ error: z9.string().optional()
934
1028
  });
935
- var wordpressSchemaDeployResultDtoSchema = z8.object({
1029
+ var wordpressSchemaDeployResultDtoSchema = z9.object({
936
1030
  env: wordpressEnvSchema,
937
- results: z8.array(wordpressSchemaDeployEntryResultDtoSchema)
1031
+ results: z9.array(wordpressSchemaDeployEntryResultDtoSchema)
938
1032
  });
939
- var wordpressSchemaStatusPageDtoSchema = z8.object({
940
- slug: z8.string(),
941
- title: z8.string(),
942
- canonrySchemas: z8.array(z8.string()),
943
- thirdPartySchemas: z8.array(z8.string()),
944
- hasCanonrySchema: z8.boolean()
1033
+ var wordpressSchemaStatusPageDtoSchema = z9.object({
1034
+ slug: z9.string(),
1035
+ title: z9.string(),
1036
+ canonrySchemas: z9.array(z9.string()),
1037
+ thirdPartySchemas: z9.array(z9.string()),
1038
+ hasCanonrySchema: z9.boolean()
945
1039
  });
946
- var wordpressSchemaStatusResultDtoSchema = z8.object({
1040
+ var wordpressSchemaStatusResultDtoSchema = z9.object({
947
1041
  env: wordpressEnvSchema,
948
- pages: z8.array(wordpressSchemaStatusPageDtoSchema)
1042
+ pages: z9.array(wordpressSchemaStatusPageDtoSchema)
949
1043
  });
950
- var wordpressOnboardStepDtoSchema = z8.object({
951
- name: z8.string(),
952
- status: z8.enum(["completed", "skipped", "failed"]),
953
- summary: z8.string().optional(),
954
- error: z8.string().optional()
1044
+ var wordpressOnboardStepDtoSchema = z9.object({
1045
+ name: z9.string(),
1046
+ status: z9.enum(["completed", "skipped", "failed"]),
1047
+ summary: z9.string().optional(),
1048
+ error: z9.string().optional()
955
1049
  });
956
- var wordpressOnboardResultDtoSchema = z8.object({
957
- projectName: z8.string(),
958
- steps: z8.array(wordpressOnboardStepDtoSchema)
1050
+ var wordpressOnboardResultDtoSchema = z9.object({
1051
+ projectName: z9.string(),
1052
+ steps: z9.array(wordpressOnboardStepDtoSchema)
959
1053
  });
960
- var wordpressDiffDtoSchema = z8.object({
961
- slug: z8.string(),
1054
+ var wordpressDiffDtoSchema = z9.object({
1055
+ slug: z9.string(),
962
1056
  live: wordpressDiffPageDtoSchema,
963
1057
  staging: wordpressDiffPageDtoSchema,
964
- hasDifferences: z8.boolean(),
965
- differences: z8.object({
966
- title: z8.boolean(),
967
- slug: z8.boolean(),
968
- content: z8.boolean(),
969
- seoTitle: z8.boolean(),
970
- seoDescription: z8.boolean(),
971
- noindex: z8.boolean(),
972
- schema: z8.boolean()
1058
+ hasDifferences: z9.boolean(),
1059
+ differences: z9.object({
1060
+ title: z9.boolean(),
1061
+ slug: z9.boolean(),
1062
+ content: z9.boolean(),
1063
+ seoTitle: z9.boolean(),
1064
+ seoDescription: z9.boolean(),
1065
+ noindex: z9.boolean(),
1066
+ schema: z9.boolean()
973
1067
  })
974
1068
  });
975
1069
 
@@ -1003,17 +1097,45 @@ var AGENT_PROVIDER_IDS = Object.values(AgentProviderIds);
1003
1097
  function isAgentProviderId(value) {
1004
1098
  return AGENT_PROVIDER_IDS.includes(value);
1005
1099
  }
1100
+ var LlmCapabilities = {
1101
+ agent: "agent",
1102
+ analyze: "analyze",
1103
+ classify: "classify"
1104
+ };
1105
+ var LLM_CAPABILITIES = Object.values(LlmCapabilities);
1106
+
1107
+ // ../contracts/src/settings.ts
1108
+ import { z as z10 } from "zod";
1109
+ var providerSummaryEntryDtoSchema = z10.object({
1110
+ name: z10.string(),
1111
+ displayName: z10.string().optional(),
1112
+ keyUrl: z10.string().optional(),
1113
+ modelHint: z10.string().optional(),
1114
+ model: z10.string().optional(),
1115
+ configured: z10.boolean(),
1116
+ quota: providerQuotaPolicySchema.optional(),
1117
+ /** Whether Vertex AI is configured for this provider (Gemini only). */
1118
+ vertexConfigured: z10.boolean().optional()
1119
+ });
1120
+ var integrationSettingsSummaryDtoSchema = z10.object({
1121
+ configured: z10.boolean()
1122
+ });
1123
+ var settingsDtoSchema = z10.object({
1124
+ providers: z10.array(providerSummaryEntryDtoSchema).default([]),
1125
+ google: integrationSettingsSummaryDtoSchema,
1126
+ bing: integrationSettingsSummaryDtoSchema
1127
+ });
1006
1128
 
1007
1129
  // ../contracts/src/snapshot.ts
1008
- import { z as z9 } from "zod";
1009
- var snapshotAccuracySchema = z9.enum(["yes", "no", "unknown", "not-mentioned"]);
1010
- var snapshotQueryListSchema = z9.array(z9.string().min(1));
1011
- var snapshotRequestSchema = z9.object({
1012
- companyName: z9.string().min(1),
1013
- domain: z9.string().min(1),
1130
+ import { z as z11 } from "zod";
1131
+ var snapshotAccuracySchema = z11.enum(["yes", "no", "unknown", "not-mentioned"]);
1132
+ var snapshotQueryListSchema = z11.array(z11.string().min(1));
1133
+ var snapshotRequestSchema = z11.object({
1134
+ companyName: z11.string().min(1),
1135
+ domain: z11.string().min(1),
1014
1136
  queries: snapshotQueryListSchema.optional(),
1015
1137
  phrases: snapshotQueryListSchema.optional(),
1016
- competitors: z9.array(z9.string().min(1)).optional().default([])
1138
+ competitors: z11.array(z11.string().min(1)).optional().default([])
1017
1139
  }).superRefine((input, ctx) => {
1018
1140
  if (input.queries !== void 0 && input.phrases !== void 0) {
1019
1141
  ctx.addIssue({
@@ -1026,121 +1148,121 @@ var snapshotRequestSchema = z9.object({
1026
1148
  function resolveSnapshotRequestQueries(input) {
1027
1149
  return input.queries ?? input.phrases ?? [];
1028
1150
  }
1029
- var snapshotCompetitorEntrySchema = z9.object({
1030
- name: z9.string(),
1031
- count: z9.number().int().nonnegative()
1032
- });
1033
- var snapshotAuditFactorSchema = z9.object({
1034
- id: z9.string(),
1035
- name: z9.string(),
1036
- weight: z9.number(),
1037
- score: z9.number(),
1038
- grade: z9.string(),
1039
- status: z9.enum(["pass", "partial", "fail"]),
1040
- findings: z9.array(z9.object({
1041
- type: z9.string(),
1042
- message: z9.string()
1151
+ var snapshotCompetitorEntrySchema = z11.object({
1152
+ name: z11.string(),
1153
+ count: z11.number().int().nonnegative()
1154
+ });
1155
+ var snapshotAuditFactorSchema = z11.object({
1156
+ id: z11.string(),
1157
+ name: z11.string(),
1158
+ weight: z11.number(),
1159
+ score: z11.number(),
1160
+ grade: z11.string(),
1161
+ status: z11.enum(["pass", "partial", "fail"]),
1162
+ findings: z11.array(z11.object({
1163
+ type: z11.string(),
1164
+ message: z11.string()
1043
1165
  })).default([]),
1044
- recommendations: z9.array(z9.string()).default([])
1045
- });
1046
- var snapshotAuditSchema = z9.object({
1047
- url: z9.string(),
1048
- finalUrl: z9.string(),
1049
- auditedAt: z9.string(),
1050
- overallScore: z9.number(),
1051
- overallGrade: z9.string(),
1052
- summary: z9.string(),
1053
- factors: z9.array(snapshotAuditFactorSchema).default([])
1054
- });
1055
- var snapshotProfileSchema = z9.object({
1056
- industry: z9.string(),
1057
- summary: z9.string(),
1058
- services: z9.array(z9.string()).default([]),
1059
- categoryTerms: z9.array(z9.string()).default([])
1060
- });
1061
- var snapshotProviderResultSchema = z9.object({
1062
- provider: z9.string(),
1063
- displayName: z9.string(),
1064
- model: z9.string().nullable().optional(),
1065
- mentioned: z9.boolean(),
1066
- cited: z9.boolean(),
1166
+ recommendations: z11.array(z11.string()).default([])
1167
+ });
1168
+ var snapshotAuditSchema = z11.object({
1169
+ url: z11.string(),
1170
+ finalUrl: z11.string(),
1171
+ auditedAt: z11.string(),
1172
+ overallScore: z11.number(),
1173
+ overallGrade: z11.string(),
1174
+ summary: z11.string(),
1175
+ factors: z11.array(snapshotAuditFactorSchema).default([])
1176
+ });
1177
+ var snapshotProfileSchema = z11.object({
1178
+ industry: z11.string(),
1179
+ summary: z11.string(),
1180
+ services: z11.array(z11.string()).default([]),
1181
+ categoryTerms: z11.array(z11.string()).default([])
1182
+ });
1183
+ var snapshotProviderResultSchema = z11.object({
1184
+ provider: z11.string(),
1185
+ displayName: z11.string(),
1186
+ model: z11.string().nullable().optional(),
1187
+ mentioned: z11.boolean(),
1188
+ cited: z11.boolean(),
1067
1189
  describedAccurately: snapshotAccuracySchema,
1068
- accuracyNotes: z9.string().nullable().optional(),
1069
- incorrectClaims: z9.array(z9.string()).default([]),
1070
- recommendedCompetitors: z9.array(z9.string()).default([]),
1071
- citedDomains: z9.array(z9.string()).default([]),
1072
- groundingSources: z9.array(groundingSourceSchema).default([]),
1073
- searchQueries: z9.array(z9.string()).default([]),
1074
- answerText: z9.string(),
1075
- error: z9.string().nullable().optional()
1076
- });
1077
- var snapshotQueryResultSchema = z9.object({
1078
- query: z9.string(),
1079
- providerResults: z9.array(snapshotProviderResultSchema).default([])
1080
- });
1081
- var snapshotSummarySchema = z9.object({
1082
- totalQueries: z9.number().int().nonnegative(),
1083
- totalProviders: z9.number().int().nonnegative(),
1084
- totalComparisons: z9.number().int().nonnegative(),
1085
- mentionCount: z9.number().int().nonnegative(),
1086
- citationCount: z9.number().int().nonnegative(),
1087
- topCompetitors: z9.array(snapshotCompetitorEntrySchema).default([]),
1088
- visibilityGap: z9.string(),
1089
- whatThisMeans: z9.array(z9.string()).default([]),
1090
- recommendedActions: z9.array(z9.string()).default([])
1091
- });
1092
- var snapshotReportSchema = z9.object({
1093
- companyName: z9.string(),
1094
- domain: z9.string(),
1095
- homepageUrl: z9.string(),
1096
- generatedAt: z9.string(),
1097
- queries: z9.array(z9.string()).default([]),
1098
- competitors: z9.array(z9.string()).default([]),
1190
+ accuracyNotes: z11.string().nullable().optional(),
1191
+ incorrectClaims: z11.array(z11.string()).default([]),
1192
+ recommendedCompetitors: z11.array(z11.string()).default([]),
1193
+ citedDomains: z11.array(z11.string()).default([]),
1194
+ groundingSources: z11.array(groundingSourceSchema).default([]),
1195
+ searchQueries: z11.array(z11.string()).default([]),
1196
+ answerText: z11.string(),
1197
+ error: z11.string().nullable().optional()
1198
+ });
1199
+ var snapshotQueryResultSchema = z11.object({
1200
+ query: z11.string(),
1201
+ providerResults: z11.array(snapshotProviderResultSchema).default([])
1202
+ });
1203
+ var snapshotSummarySchema = z11.object({
1204
+ totalQueries: z11.number().int().nonnegative(),
1205
+ totalProviders: z11.number().int().nonnegative(),
1206
+ totalComparisons: z11.number().int().nonnegative(),
1207
+ mentionCount: z11.number().int().nonnegative(),
1208
+ citationCount: z11.number().int().nonnegative(),
1209
+ topCompetitors: z11.array(snapshotCompetitorEntrySchema).default([]),
1210
+ visibilityGap: z11.string(),
1211
+ whatThisMeans: z11.array(z11.string()).default([]),
1212
+ recommendedActions: z11.array(z11.string()).default([])
1213
+ });
1214
+ var snapshotReportSchema = z11.object({
1215
+ companyName: z11.string(),
1216
+ domain: z11.string(),
1217
+ homepageUrl: z11.string(),
1218
+ generatedAt: z11.string(),
1219
+ queries: z11.array(z11.string()).default([]),
1220
+ competitors: z11.array(z11.string()).default([]),
1099
1221
  profile: snapshotProfileSchema,
1100
1222
  audit: snapshotAuditSchema,
1101
- queryResults: z9.array(snapshotQueryResultSchema).default([]),
1223
+ queryResults: z11.array(snapshotQueryResultSchema).default([]),
1102
1224
  summary: snapshotSummarySchema
1103
1225
  });
1104
1226
 
1105
1227
  // ../contracts/src/schedule.ts
1106
- import { z as z10 } from "zod";
1107
- var schedulableRunKindSchema = z10.enum(["answer-visibility", "traffic-sync"]);
1228
+ import { z as z12 } from "zod";
1229
+ var schedulableRunKindSchema = z12.enum(["answer-visibility", "traffic-sync"]);
1108
1230
  var SchedulableRunKinds = schedulableRunKindSchema.enum;
1109
- var scheduleDtoSchema = z10.object({
1110
- id: z10.string(),
1111
- projectId: z10.string(),
1231
+ var scheduleDtoSchema = z12.object({
1232
+ id: z12.string(),
1233
+ projectId: z12.string(),
1112
1234
  /** Run kind dispatched when this schedule fires. Defaults to 'answer-visibility' for legacy rows. */
1113
1235
  kind: schedulableRunKindSchema,
1114
- cronExpr: z10.string(),
1115
- preset: z10.string().nullable().optional(),
1116
- timezone: z10.string().default("UTC"),
1117
- enabled: z10.boolean().default(true),
1118
- providers: z10.array(providerNameSchema).default([]),
1236
+ cronExpr: z12.string(),
1237
+ preset: z12.string().nullable().optional(),
1238
+ timezone: z12.string().default("UTC"),
1239
+ enabled: z12.boolean().default(true),
1240
+ providers: z12.array(providerNameSchema).default([]),
1119
1241
  /** Traffic-source UUID for `kind === 'traffic-sync'` schedules. Null otherwise. */
1120
- sourceId: z10.string().nullable().optional(),
1121
- lastRunAt: z10.string().nullable().optional(),
1122
- nextRunAt: z10.string().nullable().optional(),
1123
- createdAt: z10.string(),
1124
- updatedAt: z10.string()
1242
+ sourceId: z12.string().nullable().optional(),
1243
+ lastRunAt: z12.string().nullable().optional(),
1244
+ nextRunAt: z12.string().nullable().optional(),
1245
+ createdAt: z12.string(),
1246
+ updatedAt: z12.string()
1125
1247
  });
1126
- var scheduleUpsertRequestSchema = z10.object({
1248
+ var scheduleUpsertRequestSchema = z12.object({
1127
1249
  /** Run kind. Defaults to 'answer-visibility' so existing callers don't have to change. */
1128
1250
  kind: schedulableRunKindSchema.optional(),
1129
- preset: z10.string().optional(),
1130
- cron: z10.string().optional(),
1131
- timezone: z10.string().optional().default("UTC"),
1132
- enabled: z10.boolean().optional().default(true),
1133
- providers: z10.array(providerNameSchema).optional().default([]),
1251
+ preset: z12.string().optional(),
1252
+ cron: z12.string().optional(),
1253
+ timezone: z12.string().optional().default("UTC"),
1254
+ enabled: z12.boolean().optional().default(true),
1255
+ providers: z12.array(providerNameSchema).optional().default([]),
1134
1256
  /** Required when kind === 'traffic-sync'. Forbidden for other kinds. Validated server-side. */
1135
- sourceId: z10.string().optional()
1257
+ sourceId: z12.string().optional()
1136
1258
  }).refine(
1137
1259
  (data) => data.preset && !data.cron || !data.preset && data.cron,
1138
1260
  { message: 'Exactly one of "preset" or "cron" must be provided' }
1139
1261
  );
1140
1262
 
1141
1263
  // ../contracts/src/analytics.ts
1142
- import { z as z11 } from "zod";
1143
- var visibilityMetricModeSchema = z11.enum(["mentioned", "cited"]);
1264
+ import { z as z13 } from "zod";
1265
+ var visibilityMetricModeSchema = z13.enum(["mentioned", "cited"]);
1144
1266
  var VisibilityMetricModes = visibilityMetricModeSchema.enum;
1145
1267
  function parseWindow(value) {
1146
1268
  if (value === "7d" || value === "30d" || value === "90d" || value === "all") return value;
@@ -1279,29 +1401,29 @@ function categoryLabel(category) {
1279
1401
  }
1280
1402
 
1281
1403
  // ../contracts/src/ga.ts
1282
- import { z as z12 } from "zod";
1283
- var ga4ConnectionDtoSchema = z12.object({
1284
- id: z12.string(),
1285
- projectId: z12.string(),
1286
- propertyId: z12.string(),
1287
- clientEmail: z12.string(),
1288
- connected: z12.boolean(),
1289
- createdAt: z12.string(),
1290
- updatedAt: z12.string()
1404
+ import { z as z14 } from "zod";
1405
+ var ga4ConnectionDtoSchema = z14.object({
1406
+ id: z14.string(),
1407
+ projectId: z14.string(),
1408
+ propertyId: z14.string(),
1409
+ clientEmail: z14.string(),
1410
+ connected: z14.boolean(),
1411
+ createdAt: z14.string(),
1412
+ updatedAt: z14.string()
1291
1413
  });
1292
- var ga4TrafficSnapshotDtoSchema = z12.object({
1293
- date: z12.string(),
1294
- landingPage: z12.string(),
1295
- sessions: z12.number(),
1296
- organicSessions: z12.number(),
1297
- users: z12.number()
1298
- });
1299
- var ga4SourceDimensionSchema = z12.enum(["session", "first_user", "manual_utm"]);
1300
- var ga4AiReferralDtoSchema = z12.object({
1301
- source: z12.string(),
1302
- medium: z12.string(),
1303
- sessions: z12.number(),
1304
- users: z12.number(),
1414
+ var ga4TrafficSnapshotDtoSchema = z14.object({
1415
+ date: z14.string(),
1416
+ landingPage: z14.string(),
1417
+ sessions: z14.number(),
1418
+ organicSessions: z14.number(),
1419
+ users: z14.number()
1420
+ });
1421
+ var ga4SourceDimensionSchema = z14.enum(["session", "first_user", "manual_utm"]);
1422
+ var ga4AiReferralDtoSchema = z14.object({
1423
+ source: z14.string(),
1424
+ medium: z14.string(),
1425
+ sessions: z14.number(),
1426
+ users: z14.number(),
1305
1427
  /**
1306
1428
  * The winning attribution dimension for this (source, medium) tuple — the
1307
1429
  * one with the highest session count. GA4 emits one row per dimension
@@ -1311,121 +1433,144 @@ var ga4AiReferralDtoSchema = z12.object({
1311
1433
  */
1312
1434
  sourceDimension: ga4SourceDimensionSchema
1313
1435
  });
1314
- var ga4AiReferralLandingPageDtoSchema = z12.object({
1315
- source: z12.string(),
1316
- medium: z12.string(),
1436
+ var ga4AiReferralLandingPageDtoSchema = z14.object({
1437
+ source: z14.string(),
1438
+ medium: z14.string(),
1317
1439
  /**
1318
1440
  * The winning attribution dimension for this (source, medium, landingPage)
1319
1441
  * tuple — the one with the highest session count.
1320
1442
  */
1321
1443
  sourceDimension: ga4SourceDimensionSchema,
1322
- landingPage: z12.string(),
1323
- sessions: z12.number(),
1324
- users: z12.number()
1325
- });
1326
- var ga4SocialReferralDtoSchema = z12.object({
1327
- source: z12.string(),
1328
- medium: z12.string(),
1329
- sessions: z12.number(),
1330
- users: z12.number(),
1444
+ landingPage: z14.string(),
1445
+ sessions: z14.number(),
1446
+ users: z14.number()
1447
+ });
1448
+ var ga4SocialReferralDtoSchema = z14.object({
1449
+ source: z14.string(),
1450
+ medium: z14.string(),
1451
+ sessions: z14.number(),
1452
+ users: z14.number(),
1331
1453
  /** GA4 default channel group (e.g. 'Organic Social', 'Paid Social') */
1332
- channelGroup: z12.string()
1454
+ channelGroup: z14.string()
1333
1455
  });
1334
- var ga4ChannelBucketDtoSchema = z12.object({
1335
- sessions: z12.number(),
1336
- sharePct: z12.number(),
1337
- sharePctDisplay: z12.string()
1456
+ var ga4ChannelBucketDtoSchema = z14.object({
1457
+ sessions: z14.number(),
1458
+ sharePct: z14.number(),
1459
+ sharePctDisplay: z14.string()
1338
1460
  });
1339
- var ga4ChannelBreakdownDtoSchema = z12.object({
1461
+ var ga4ChannelBreakdownDtoSchema = z14.object({
1340
1462
  organic: ga4ChannelBucketDtoSchema,
1341
1463
  social: ga4ChannelBucketDtoSchema,
1342
1464
  direct: ga4ChannelBucketDtoSchema,
1343
1465
  ai: ga4ChannelBucketDtoSchema,
1344
1466
  other: ga4ChannelBucketDtoSchema
1345
1467
  });
1346
- var ga4TrafficSummaryDtoSchema = z12.object({
1347
- totalSessions: z12.number(),
1348
- totalOrganicSessions: z12.number(),
1468
+ var ga4TrafficSummaryDtoSchema = z14.object({
1469
+ totalSessions: z14.number(),
1470
+ totalOrganicSessions: z14.number(),
1349
1471
  /** Direct-channel sessions (sessions with no source — bookmarks, typed URLs, AI-driven traffic with stripped referrer). 0 for legacy rows from before the column was added. */
1350
- totalDirectSessions: z12.number(),
1351
- totalUsers: z12.number(),
1352
- topPages: z12.array(z12.object({
1353
- landingPage: z12.string(),
1354
- sessions: z12.number(),
1355
- organicSessions: z12.number(),
1472
+ totalDirectSessions: z14.number(),
1473
+ totalUsers: z14.number(),
1474
+ topPages: z14.array(z14.object({
1475
+ landingPage: z14.string(),
1476
+ sessions: z14.number(),
1477
+ organicSessions: z14.number(),
1356
1478
  /** Per-page Direct-channel sessions. 0 for legacy rows. */
1357
- directSessions: z12.number(),
1358
- users: z12.number()
1479
+ directSessions: z14.number(),
1480
+ users: z14.number()
1359
1481
  })),
1360
- aiReferrals: z12.array(ga4AiReferralDtoSchema),
1361
- aiReferralLandingPages: z12.array(ga4AiReferralLandingPageDtoSchema),
1482
+ aiReferrals: z14.array(ga4AiReferralDtoSchema),
1483
+ aiReferralLandingPages: z14.array(ga4AiReferralLandingPageDtoSchema),
1362
1484
  /** Deduped AI session total: MAX(sessions) per date+source+medium across attribution dimensions, then summed. Cross-cutting: can overlap with Direct/Organic/Social via firstUserSource. */
1363
- aiSessionsDeduped: z12.number(),
1485
+ aiSessionsDeduped: z14.number(),
1364
1486
  /** Deduped AI user total: MAX(users) per date+source+medium across attribution dimensions, then summed. */
1365
- aiUsersDeduped: z12.number(),
1487
+ aiUsersDeduped: z14.number(),
1366
1488
  /** AI sessions whose CURRENT sessionSource matched an AI engine. Can overlap with raw Organic/Social/Direct totals; `channelBreakdown` removes those overlaps for display. */
1367
- aiSessionsBySession: z12.number(),
1489
+ aiSessionsBySession: z14.number(),
1368
1490
  /** AI users whose CURRENT sessionSource matched an AI engine. Can overlap with raw Organic/Social/Direct totals. */
1369
- aiUsersBySession: z12.number(),
1370
- socialReferrals: z12.array(ga4SocialReferralDtoSchema),
1491
+ aiUsersBySession: z14.number(),
1492
+ socialReferrals: z14.array(ga4SocialReferralDtoSchema),
1371
1493
  /** Total social sessions (session-scoped, no cross-dimension dedup needed). */
1372
- socialSessions: z12.number(),
1494
+ socialSessions: z14.number(),
1373
1495
  /** Total social users (session-scoped, no cross-dimension dedup needed). */
1374
- socialUsers: z12.number(),
1496
+ socialUsers: z14.number(),
1375
1497
  /** Five disjoint buckets used for the channel breakdown. Known AI session-source matches are removed from their native GA4 bucket before shares are computed. */
1376
1498
  channelBreakdown: ga4ChannelBreakdownDtoSchema,
1377
1499
  /** Organic sessions as a percentage of total sessions (0–100, rounded). */
1378
- organicSharePct: z12.number(),
1500
+ organicSharePct: z14.number(),
1379
1501
  /** Deduped AI sessions as a percentage of total sessions (0–100, rounded). Cross-cutting: can overlap with Direct/Organic/Social. */
1380
- aiSharePct: z12.number(),
1502
+ aiSharePct: z14.number(),
1381
1503
  /** Session-source-only AI sessions as a percentage of total sessions (0–100, rounded). Can overlap with raw Organic/Social/Direct totals. */
1382
- aiSharePctBySession: z12.number(),
1504
+ aiSharePctBySession: z14.number(),
1383
1505
  /** Direct-channel sessions as a percentage of total sessions (0–100, rounded). */
1384
- directSharePct: z12.number(),
1506
+ directSharePct: z14.number(),
1385
1507
  /** Social sessions as a percentage of total sessions (0–100, rounded). */
1386
- socialSharePct: z12.number(),
1508
+ socialSharePct: z14.number(),
1387
1509
  /** Display string for organicSharePct: 'X%', '<1%' for non-zero shares that round below 1, or '—' when sessions exist but total is unknown (partial sync). */
1388
- organicSharePctDisplay: z12.string(),
1510
+ organicSharePctDisplay: z14.string(),
1389
1511
  /** Display string for aiSharePct: 'X%', '<1%' for non-zero shares that round below 1, or '—' when sessions exist but total is unknown (partial sync). */
1390
- aiSharePctDisplay: z12.string(),
1512
+ aiSharePctDisplay: z14.string(),
1391
1513
  /** Display string for aiSharePctBySession: 'X%', '<1%' for non-zero shares that round below 1, or '—' when sessions exist but total is unknown (partial sync). */
1392
- aiSharePctBySessionDisplay: z12.string(),
1514
+ aiSharePctBySessionDisplay: z14.string(),
1393
1515
  /** Display string for directSharePct: 'X%', '<1%' for non-zero shares that round below 1, or '—' when sessions exist but total is unknown (partial sync). */
1394
- directSharePctDisplay: z12.string(),
1516
+ directSharePctDisplay: z14.string(),
1395
1517
  /** Display string for socialSharePct: 'X%', '<1%' for non-zero shares that round below 1, or '—' when sessions exist but total is unknown (partial sync). */
1396
- socialSharePctDisplay: z12.string(),
1518
+ socialSharePctDisplay: z14.string(),
1397
1519
  /** Sessions not covered by Organic, Social, Direct, or AI (session) channels — e.g. Referral, Email, Paid Search, Display. Always non-negative; clamped to 0 when the four disjoint channels sum above total (rounding edge). */
1398
- otherSessions: z12.number(),
1520
+ otherSessions: z14.number(),
1399
1521
  /** Other sessions as a percentage of total sessions (0–100, rounded). */
1400
- otherSharePct: z12.number(),
1522
+ otherSharePct: z14.number(),
1401
1523
  /** Display string for otherSharePct: 'X%', '<1%' for non-zero shares that round below 1, or '—' when sessions exist but total is unknown (partial sync). */
1402
- otherSharePctDisplay: z12.string(),
1403
- lastSyncedAt: z12.string().nullable()
1404
- });
1405
- var ga4AiReferralHistoryEntrySchema = z12.object({
1406
- date: z12.string(),
1407
- source: z12.string(),
1408
- medium: z12.string(),
1409
- landingPage: z12.string(),
1410
- sessions: z12.number(),
1411
- users: z12.number(),
1524
+ otherSharePctDisplay: z14.string(),
1525
+ lastSyncedAt: z14.string().nullable()
1526
+ });
1527
+ var ga4StatusDtoSchema = z14.object({
1528
+ connected: z14.boolean(),
1529
+ propertyId: z14.string().nullable(),
1530
+ clientEmail: z14.string().nullable(),
1531
+ authMethod: z14.enum(["service-account", "oauth"]).nullable(),
1532
+ lastSyncedAt: z14.string().nullable(),
1533
+ createdAt: z14.string().nullable().optional(),
1534
+ updatedAt: z14.string().nullable().optional()
1535
+ });
1536
+ var ga4SyncResponseDtoSchema = z14.object({
1537
+ synced: z14.boolean(),
1538
+ rowCount: z14.number().int().nonnegative(),
1539
+ aiReferralCount: z14.number().int().nonnegative(),
1540
+ socialReferralCount: z14.number().int().nonnegative(),
1541
+ days: z14.number().int().nonnegative(),
1542
+ syncedAt: z14.string(),
1543
+ /**
1544
+ * Components that were written this run. Present when `only` is set.
1545
+ * Always includes `traffic` and `summary` (the share denominator) plus
1546
+ * the requested channel breakdown — `ai` and/or `social`.
1547
+ */
1548
+ syncedComponents: z14.array(z14.string()).optional()
1549
+ });
1550
+ var ga4AiReferralHistoryEntrySchema = z14.object({
1551
+ date: z14.string(),
1552
+ source: z14.string(),
1553
+ medium: z14.string(),
1554
+ landingPage: z14.string(),
1555
+ sessions: z14.number(),
1556
+ users: z14.number(),
1412
1557
  /** Which GA4 dimension this row came from: session (sessionSource), first_user (firstUserSource), or manual_utm (utm_source parameter) */
1413
1558
  sourceDimension: ga4SourceDimensionSchema
1414
1559
  });
1415
- var ga4SocialReferralHistoryEntrySchema = z12.object({
1416
- date: z12.string(),
1417
- source: z12.string(),
1418
- medium: z12.string(),
1419
- sessions: z12.number(),
1420
- users: z12.number(),
1560
+ var ga4SocialReferralHistoryEntrySchema = z14.object({
1561
+ date: z14.string(),
1562
+ source: z14.string(),
1563
+ medium: z14.string(),
1564
+ sessions: z14.number(),
1565
+ users: z14.number(),
1421
1566
  /** GA4 default channel group (e.g. 'Organic Social', 'Paid Social') */
1422
- channelGroup: z12.string()
1567
+ channelGroup: z14.string()
1423
1568
  });
1424
- var ga4SessionHistoryEntrySchema = z12.object({
1425
- date: z12.string(),
1426
- sessions: z12.number(),
1427
- organicSessions: z12.number(),
1428
- users: z12.number()
1569
+ var ga4SessionHistoryEntrySchema = z14.object({
1570
+ date: z14.string(),
1571
+ sessions: z14.number(),
1572
+ organicSessions: z14.number(),
1573
+ users: z14.number()
1429
1574
  });
1430
1575
 
1431
1576
  // ../contracts/src/answer-visibility.ts
@@ -1593,121 +1738,149 @@ function escapeRegExp(value) {
1593
1738
  }
1594
1739
 
1595
1740
  // ../contracts/src/agent.ts
1596
- import { z as z13 } from "zod";
1597
- var memorySourceSchema = z13.enum(["aero", "user", "compaction"]);
1741
+ import { z as z15 } from "zod";
1742
+ var agentProviderIdSchema = z15.enum(["claude", "openai", "gemini", "zai"]);
1743
+ var agentProviderOptionDtoSchema = z15.object({
1744
+ /** Stable identifier — what clients pass back as `provider` on the prompt endpoint. */
1745
+ id: agentProviderIdSchema,
1746
+ /** Human-readable label for UI pickers, e.g. "Anthropic (Claude)". */
1747
+ label: z15.string(),
1748
+ /** Default model if the caller doesn't pick one. */
1749
+ defaultModel: z15.string(),
1750
+ /** Whether a usable API key was found (config.yaml or provider env var). */
1751
+ configured: z15.boolean(),
1752
+ /**
1753
+ * Where the key resolved from, if any. `null` when `configured === false`.
1754
+ * Surfaced so the UI can nudge users toward their preferred source of truth.
1755
+ */
1756
+ keySource: z15.enum(["config", "env"]).nullable()
1757
+ });
1758
+ var agentProvidersResponseDtoSchema = z15.object({
1759
+ /**
1760
+ * Every provider Aero knows about. `configured === false` entries are
1761
+ * included so the UI can render them disabled with an onboarding hint.
1762
+ */
1763
+ providers: z15.array(agentProviderOptionDtoSchema).default([]),
1764
+ /**
1765
+ * Provider Aero auto-picks when no explicit override is passed. Null if
1766
+ * nothing is configured (install never exchanged a key).
1767
+ */
1768
+ defaultProvider: agentProviderIdSchema.nullable()
1769
+ });
1770
+ var memorySourceSchema = z15.enum(["aero", "user", "compaction"]);
1598
1771
  var MemorySources = memorySourceSchema.enum;
1599
1772
  var AGENT_MEMORY_VALUE_MAX_BYTES = 2 * 1024;
1600
1773
  var AGENT_MEMORY_KEY_MAX_LENGTH = 128;
1601
- var agentMemoryUpsertRequestSchema = z13.object({
1602
- key: z13.string().min(1).max(AGENT_MEMORY_KEY_MAX_LENGTH),
1603
- value: z13.string().min(1)
1774
+ var agentMemoryUpsertRequestSchema = z15.object({
1775
+ key: z15.string().min(1).max(AGENT_MEMORY_KEY_MAX_LENGTH),
1776
+ value: z15.string().min(1)
1604
1777
  });
1605
- var agentMemoryDeleteRequestSchema = z13.object({
1606
- key: z13.string().min(1).max(AGENT_MEMORY_KEY_MAX_LENGTH)
1778
+ var agentMemoryDeleteRequestSchema = z15.object({
1779
+ key: z15.string().min(1).max(AGENT_MEMORY_KEY_MAX_LENGTH)
1607
1780
  });
1608
1781
 
1609
1782
  // ../contracts/src/backlinks.ts
1610
- import { z as z14 } from "zod";
1611
- var ccReleaseSyncStatusSchema = z14.enum(["queued", "downloading", "querying", "ready", "failed"]);
1783
+ import { z as z16 } from "zod";
1784
+ var ccReleaseSyncStatusSchema = z16.enum(["queued", "downloading", "querying", "ready", "failed"]);
1612
1785
  var CcReleaseSyncStatuses = ccReleaseSyncStatusSchema.enum;
1613
- var ccReleaseSyncDtoSchema = z14.object({
1614
- id: z14.string(),
1615
- release: z14.string(),
1786
+ var ccReleaseSyncDtoSchema = z16.object({
1787
+ id: z16.string(),
1788
+ release: z16.string(),
1616
1789
  status: ccReleaseSyncStatusSchema,
1617
- phaseDetail: z14.string().nullable().optional(),
1618
- vertexPath: z14.string().nullable().optional(),
1619
- edgesPath: z14.string().nullable().optional(),
1620
- vertexSha256: z14.string().nullable().optional(),
1621
- edgesSha256: z14.string().nullable().optional(),
1622
- vertexBytes: z14.number().int().nullable().optional(),
1623
- edgesBytes: z14.number().int().nullable().optional(),
1624
- projectsProcessed: z14.number().int().nullable().optional(),
1625
- domainsDiscovered: z14.number().int().nullable().optional(),
1626
- downloadStartedAt: z14.string().nullable().optional(),
1627
- downloadFinishedAt: z14.string().nullable().optional(),
1628
- queryStartedAt: z14.string().nullable().optional(),
1629
- queryFinishedAt: z14.string().nullable().optional(),
1630
- error: z14.string().nullable().optional(),
1631
- createdAt: z14.string(),
1632
- updatedAt: z14.string()
1633
- });
1634
- var backlinkDomainDtoSchema = z14.object({
1635
- linkingDomain: z14.string(),
1636
- numHosts: z14.number().int()
1637
- });
1638
- var backlinkSummaryDtoSchema = z14.object({
1639
- projectId: z14.string(),
1640
- release: z14.string(),
1641
- targetDomain: z14.string(),
1642
- totalLinkingDomains: z14.number().int(),
1643
- totalHosts: z14.number().int(),
1644
- top10HostsShare: z14.string(),
1645
- queriedAt: z14.string(),
1790
+ phaseDetail: z16.string().nullable().optional(),
1791
+ vertexPath: z16.string().nullable().optional(),
1792
+ edgesPath: z16.string().nullable().optional(),
1793
+ vertexSha256: z16.string().nullable().optional(),
1794
+ edgesSha256: z16.string().nullable().optional(),
1795
+ vertexBytes: z16.number().int().nullable().optional(),
1796
+ edgesBytes: z16.number().int().nullable().optional(),
1797
+ projectsProcessed: z16.number().int().nullable().optional(),
1798
+ domainsDiscovered: z16.number().int().nullable().optional(),
1799
+ downloadStartedAt: z16.string().nullable().optional(),
1800
+ downloadFinishedAt: z16.string().nullable().optional(),
1801
+ queryStartedAt: z16.string().nullable().optional(),
1802
+ queryFinishedAt: z16.string().nullable().optional(),
1803
+ error: z16.string().nullable().optional(),
1804
+ createdAt: z16.string(),
1805
+ updatedAt: z16.string()
1806
+ });
1807
+ var backlinkDomainDtoSchema = z16.object({
1808
+ linkingDomain: z16.string(),
1809
+ numHosts: z16.number().int()
1810
+ });
1811
+ var backlinkSummaryDtoSchema = z16.object({
1812
+ projectId: z16.string(),
1813
+ release: z16.string(),
1814
+ targetDomain: z16.string(),
1815
+ totalLinkingDomains: z16.number().int(),
1816
+ totalHosts: z16.number().int(),
1817
+ top10HostsShare: z16.string(),
1818
+ queriedAt: z16.string(),
1646
1819
  // Populated when the response is filtered (e.g. ?excludeCrawlers=1).
1647
1820
  // Counts the rows omitted from totalLinkingDomains/totalHosts so callers
1648
1821
  // can show "N hidden" hints without re-deriving them.
1649
- excludedLinkingDomains: z14.number().int().optional(),
1650
- excludedHosts: z14.number().int().optional()
1822
+ excludedLinkingDomains: z16.number().int().optional(),
1823
+ excludedHosts: z16.number().int().optional()
1651
1824
  });
1652
- var backlinkListResponseSchema = z14.object({
1825
+ var backlinkListResponseSchema = z16.object({
1653
1826
  summary: backlinkSummaryDtoSchema.nullable(),
1654
- total: z14.number().int(),
1655
- rows: z14.array(backlinkDomainDtoSchema)
1656
- });
1657
- var backlinkHistoryEntrySchema = z14.object({
1658
- release: z14.string(),
1659
- totalLinkingDomains: z14.number().int(),
1660
- totalHosts: z14.number().int(),
1661
- top10HostsShare: z14.string(),
1662
- queriedAt: z14.string()
1663
- });
1664
- var backlinksInstallStatusDtoSchema = z14.object({
1665
- duckdbInstalled: z14.boolean(),
1666
- duckdbVersion: z14.string().nullable().optional(),
1667
- duckdbSpec: z14.string(),
1668
- pluginDir: z14.string()
1669
- });
1670
- var backlinksInstallResultDtoSchema = z14.object({
1671
- installed: z14.boolean(),
1672
- version: z14.string(),
1673
- path: z14.string(),
1674
- alreadyPresent: z14.boolean()
1675
- });
1676
- var ccAvailableReleaseSchema = z14.object({
1677
- release: z14.string(),
1678
- vertexUrl: z14.string(),
1679
- edgesUrl: z14.string(),
1680
- vertexBytes: z14.number().int().nullable(),
1681
- edgesBytes: z14.number().int().nullable(),
1682
- lastModified: z14.string().nullable()
1683
- });
1684
- var ccCachedReleaseSchema = z14.object({
1685
- release: z14.string(),
1827
+ total: z16.number().int(),
1828
+ rows: z16.array(backlinkDomainDtoSchema)
1829
+ });
1830
+ var backlinkHistoryEntrySchema = z16.object({
1831
+ release: z16.string(),
1832
+ totalLinkingDomains: z16.number().int(),
1833
+ totalHosts: z16.number().int(),
1834
+ top10HostsShare: z16.string(),
1835
+ queriedAt: z16.string()
1836
+ });
1837
+ var backlinksInstallStatusDtoSchema = z16.object({
1838
+ duckdbInstalled: z16.boolean(),
1839
+ duckdbVersion: z16.string().nullable().optional(),
1840
+ duckdbSpec: z16.string(),
1841
+ pluginDir: z16.string()
1842
+ });
1843
+ var backlinksInstallResultDtoSchema = z16.object({
1844
+ installed: z16.boolean(),
1845
+ version: z16.string(),
1846
+ path: z16.string(),
1847
+ alreadyPresent: z16.boolean()
1848
+ });
1849
+ var ccAvailableReleaseSchema = z16.object({
1850
+ release: z16.string(),
1851
+ vertexUrl: z16.string(),
1852
+ edgesUrl: z16.string(),
1853
+ vertexBytes: z16.number().int().nullable(),
1854
+ edgesBytes: z16.number().int().nullable(),
1855
+ lastModified: z16.string().nullable()
1856
+ });
1857
+ var ccCachedReleaseSchema = z16.object({
1858
+ release: z16.string(),
1686
1859
  syncStatus: ccReleaseSyncStatusSchema.nullable(),
1687
- bytes: z14.number().int(),
1688
- lastUsedAt: z14.string().nullable()
1860
+ bytes: z16.number().int(),
1861
+ lastUsedAt: z16.string().nullable()
1689
1862
  });
1690
1863
 
1691
1864
  // ../contracts/src/composites.ts
1692
- import { z as z15 } from "zod";
1693
- var searchHitKindSchema = z15.enum(["snapshot", "insight"]);
1694
- var projectSearchSnapshotHitSchema = z15.object({
1695
- kind: z15.literal("snapshot"),
1696
- id: z15.string(),
1697
- runId: z15.string(),
1698
- query: z15.string(),
1699
- provider: z15.string(),
1700
- model: z15.string().nullable(),
1865
+ import { z as z17 } from "zod";
1866
+ var searchHitKindSchema = z17.enum(["snapshot", "insight"]);
1867
+ var projectSearchSnapshotHitSchema = z17.object({
1868
+ kind: z17.literal("snapshot"),
1869
+ id: z17.string(),
1870
+ runId: z17.string(),
1871
+ query: z17.string(),
1872
+ provider: z17.string(),
1873
+ model: z17.string().nullable(),
1701
1874
  citationState: citationStateSchema,
1702
- matchedField: z15.enum(["answerText", "citedDomains", "searchQueries", "query"]),
1703
- snippet: z15.string(),
1704
- createdAt: z15.string()
1705
- });
1706
- var projectSearchInsightHitSchema = z15.object({
1707
- kind: z15.literal("insight"),
1708
- id: z15.string(),
1709
- runId: z15.string().nullable(),
1710
- type: z15.enum([
1875
+ matchedField: z17.enum(["answerText", "citedDomains", "searchQueries", "query"]),
1876
+ snippet: z17.string(),
1877
+ createdAt: z17.string()
1878
+ });
1879
+ var projectSearchInsightHitSchema = z17.object({
1880
+ kind: z17.literal("insight"),
1881
+ id: z17.string(),
1882
+ runId: z17.string().nullable(),
1883
+ type: z17.enum([
1711
1884
  "regression",
1712
1885
  "gain",
1713
1886
  "opportunity",
@@ -1717,29 +1890,29 @@ var projectSearchInsightHitSchema = z15.object({
1717
1890
  "competitor-gained",
1718
1891
  "competitor-lost"
1719
1892
  ]),
1720
- severity: z15.enum(["critical", "high", "medium", "low"]),
1721
- title: z15.string(),
1722
- query: z15.string(),
1723
- provider: z15.string(),
1724
- matchedField: z15.enum(["title", "query", "recommendation", "cause"]),
1725
- snippet: z15.string(),
1726
- dismissed: z15.boolean(),
1727
- createdAt: z15.string()
1728
- });
1729
- var projectSearchHitSchema = z15.discriminatedUnion("kind", [
1893
+ severity: z17.enum(["critical", "high", "medium", "low"]),
1894
+ title: z17.string(),
1895
+ query: z17.string(),
1896
+ provider: z17.string(),
1897
+ matchedField: z17.enum(["title", "query", "recommendation", "cause"]),
1898
+ snippet: z17.string(),
1899
+ dismissed: z17.boolean(),
1900
+ createdAt: z17.string()
1901
+ });
1902
+ var projectSearchHitSchema = z17.discriminatedUnion("kind", [
1730
1903
  projectSearchSnapshotHitSchema,
1731
1904
  projectSearchInsightHitSchema
1732
1905
  ]);
1733
- var projectSearchResponseSchema = z15.object({
1734
- query: z15.string(),
1735
- totalHits: z15.number().int().nonnegative(),
1736
- truncated: z15.boolean(),
1737
- hits: z15.array(projectSearchHitSchema)
1906
+ var projectSearchResponseSchema = z17.object({
1907
+ query: z17.string(),
1908
+ totalHits: z17.number().int().nonnegative(),
1909
+ truncated: z17.boolean(),
1910
+ hits: z17.array(projectSearchHitSchema)
1738
1911
  });
1739
1912
 
1740
1913
  // ../contracts/src/content.ts
1741
- import { z as z16 } from "zod";
1742
- var contentActionSchema = z16.enum(["create", "expand", "refresh", "add-schema"]);
1914
+ import { z as z18 } from "zod";
1915
+ var contentActionSchema = z18.enum(["create", "expand", "refresh", "add-schema"]);
1743
1916
  var ContentActions = contentActionSchema.enum;
1744
1917
  function contentActionLabel(action) {
1745
1918
  switch (action) {
@@ -1753,9 +1926,9 @@ function contentActionLabel(action) {
1753
1926
  return "Add schema";
1754
1927
  }
1755
1928
  }
1756
- var demandSourceSchema = z16.enum(["gsc", "competitor-evidence", "both"]);
1929
+ var demandSourceSchema = z18.enum(["gsc", "competitor-evidence", "both"]);
1757
1930
  var DemandSources = demandSourceSchema.enum;
1758
- var actionConfidenceSchema = z16.enum(["high", "medium", "low"]);
1931
+ var actionConfidenceSchema = z18.enum(["high", "medium", "low"]);
1759
1932
  var ActionConfidences = actionConfidenceSchema.enum;
1760
1933
  function actionConfidenceLabel(confidence) {
1761
1934
  switch (confidence) {
@@ -1767,7 +1940,7 @@ function actionConfidenceLabel(confidence) {
1767
1940
  return "Low";
1768
1941
  }
1769
1942
  }
1770
- var pageTypeSchema = z16.enum([
1943
+ var pageTypeSchema = z18.enum([
1771
1944
  "blog-post",
1772
1945
  "comparison",
1773
1946
  "listicle",
@@ -1776,7 +1949,7 @@ var pageTypeSchema = z16.enum([
1776
1949
  "glossary"
1777
1950
  ]);
1778
1951
  var PageTypes = pageTypeSchema.enum;
1779
- var contentActionStateSchema = z16.enum([
1952
+ var contentActionStateSchema = z18.enum([
1780
1953
  "proposed",
1781
1954
  "briefed",
1782
1955
  "payload-generated",
@@ -1786,88 +1959,136 @@ var contentActionStateSchema = z16.enum([
1786
1959
  "dismissed"
1787
1960
  ]);
1788
1961
  var ContentActionStates = contentActionStateSchema.enum;
1789
- var ourBestPageSchema = z16.object({
1790
- url: z16.string(),
1791
- gscImpressions: z16.number().nonnegative(),
1792
- gscClicks: z16.number().nonnegative(),
1962
+ var ourBestPageSchema = z18.object({
1963
+ url: z18.string(),
1964
+ gscImpressions: z18.number().nonnegative(),
1965
+ gscClicks: z18.number().nonnegative(),
1793
1966
  // Null when the page came from the inventory fallback (no GSC ranking data).
1794
- gscAvgPosition: z16.number().nonnegative().nullable(),
1795
- organicSessions: z16.number().nonnegative()
1796
- });
1797
- var winningCompetitorSchema = z16.object({
1798
- domain: z16.string(),
1799
- url: z16.string(),
1800
- title: z16.string(),
1801
- citationCount: z16.number().int().nonnegative()
1802
- });
1803
- var scoreBreakdownSchema = z16.object({
1804
- demand: z16.number(),
1805
- competitor: z16.number(),
1806
- absence: z16.number(),
1807
- gapSeverity: z16.number()
1808
- });
1809
- var existingActionRefSchema = z16.object({
1810
- actionId: z16.string(),
1967
+ gscAvgPosition: z18.number().nonnegative().nullable(),
1968
+ organicSessions: z18.number().nonnegative()
1969
+ });
1970
+ var winningCompetitorSchema = z18.object({
1971
+ domain: z18.string(),
1972
+ url: z18.string(),
1973
+ title: z18.string(),
1974
+ citationCount: z18.number().int().nonnegative()
1975
+ });
1976
+ var scoreBreakdownSchema = z18.object({
1977
+ demand: z18.number(),
1978
+ competitor: z18.number(),
1979
+ absence: z18.number(),
1980
+ gapSeverity: z18.number()
1981
+ });
1982
+ var existingActionRefSchema = z18.object({
1983
+ actionId: z18.string(),
1811
1984
  state: contentActionStateSchema,
1812
- lastUpdated: z16.string()
1985
+ lastUpdated: z18.string()
1813
1986
  });
1814
- var contentTargetRowDtoSchema = z16.object({
1815
- targetRef: z16.string(),
1816
- query: z16.string(),
1987
+ var contentTargetRowDtoSchema = z18.object({
1988
+ targetRef: z18.string(),
1989
+ query: z18.string(),
1817
1990
  action: contentActionSchema,
1818
1991
  ourBestPage: ourBestPageSchema.nullable(),
1819
1992
  winningCompetitor: winningCompetitorSchema.nullable(),
1820
- score: z16.number(),
1993
+ score: z18.number(),
1821
1994
  scoreBreakdown: scoreBreakdownSchema,
1822
- drivers: z16.array(z16.string()),
1995
+ drivers: z18.array(z18.string()),
1823
1996
  demandSource: demandSourceSchema,
1824
1997
  actionConfidence: actionConfidenceSchema,
1825
1998
  existingAction: existingActionRefSchema.nullable()
1826
1999
  });
1827
- var contentTargetsResponseDtoSchema = z16.object({
1828
- targets: z16.array(contentTargetRowDtoSchema),
1829
- contextMetrics: z16.object({
1830
- totalAiReferralSessions: z16.number().int().nonnegative(),
1831
- latestRunId: z16.string(),
1832
- runTimestamp: z16.string()
2000
+ var contentTargetsResponseDtoSchema = z18.object({
2001
+ targets: z18.array(contentTargetRowDtoSchema),
2002
+ contextMetrics: z18.object({
2003
+ totalAiReferralSessions: z18.number().int().nonnegative(),
2004
+ latestRunId: z18.string(),
2005
+ runTimestamp: z18.string()
1833
2006
  })
1834
2007
  });
1835
- var contentGroundingSourceSchema = z16.object({
1836
- uri: z16.string(),
1837
- title: z16.string(),
1838
- domain: z16.string(),
1839
- isOurDomain: z16.boolean(),
1840
- isCompetitor: z16.boolean(),
1841
- citationCount: z16.number().int().nonnegative(),
1842
- providers: z16.array(providerNameSchema)
1843
- });
1844
- var contentSourceRowDtoSchema = z16.object({
1845
- query: z16.string(),
1846
- groundingSources: z16.array(contentGroundingSourceSchema)
1847
- });
1848
- var contentSourcesResponseDtoSchema = z16.object({
1849
- sources: z16.array(contentSourceRowDtoSchema),
1850
- latestRunId: z16.string()
1851
- });
1852
- var contentGapRowDtoSchema = z16.object({
1853
- query: z16.string(),
1854
- competitorDomains: z16.array(z16.string()),
1855
- competitorCount: z16.number().int().nonnegative(),
1856
- missRate: z16.number().min(0).max(1),
1857
- lastSeenInRunId: z16.string()
1858
- });
1859
- var contentGapsResponseDtoSchema = z16.object({
1860
- gaps: z16.array(contentGapRowDtoSchema),
1861
- latestRunId: z16.string()
2008
+ var contentTargetDismissalDtoSchema = z18.object({
2009
+ targetRef: z18.string(),
2010
+ addressedUrl: z18.string().nullable(),
2011
+ note: z18.string().nullable(),
2012
+ dismissedAt: z18.string()
2013
+ });
2014
+ var contentTargetDismissalsResponseDtoSchema = z18.object({
2015
+ dismissals: z18.array(contentTargetDismissalDtoSchema)
2016
+ });
2017
+ var contentTargetDismissRequestSchema = z18.object({
2018
+ targetRef: z18.string().min(1),
2019
+ /** URL of the page the user wrote that addresses this recommendation. Stored verbatim for the audit trail; not currently used to suppress the slug-token matcher. */
2020
+ addressedUrl: z18.string().url().optional(),
2021
+ /** Free-form note (e.g. "covered in our Q1 content sprint"). 500 char cap is the API surface limit; the DB column is unbounded. */
2022
+ note: z18.string().max(500).optional()
2023
+ });
2024
+ var recommendationExplanationDtoSchema = z18.object({
2025
+ targetRef: z18.string(),
2026
+ /** Version of the prompt template used. Bumping the version invalidates the cache forward without touching the table. */
2027
+ promptVersion: z18.string(),
2028
+ /** Provider that produced the explanation (e.g. "claude", "gemini"). */
2029
+ provider: z18.string(),
2030
+ /** Model id within that provider (e.g. "claude-sonnet-4-6"). */
2031
+ model: z18.string(),
2032
+ /** Markdown-formatted rationale + recommended next steps. */
2033
+ responseText: z18.string(),
2034
+ /** Estimated cost in millicents (1/100 of a cent). 0 when unknown. */
2035
+ costMillicents: z18.number().int().nonnegative(),
2036
+ generatedAt: z18.string()
2037
+ });
2038
+ var recommendationExplainRequestSchema = z18.object({
2039
+ /**
2040
+ * Optional provider override (e.g. "claude" to force Claude even if
2041
+ * the project's default is Gemini). Falls through to project default
2042
+ * → auto-detect when omitted.
2043
+ */
2044
+ provider: z18.string().optional(),
2045
+ /**
2046
+ * Optional model override within the chosen provider. Falls through to
2047
+ * the `analyze`-tier default model when omitted.
2048
+ */
2049
+ model: z18.string().optional(),
2050
+ /**
2051
+ * Force a fresh LLM call even if a cached explanation exists for the
2052
+ * current prompt version. Use sparingly — defeats the cache.
2053
+ */
2054
+ forceRefresh: z18.boolean().optional()
2055
+ });
2056
+ var contentGroundingSourceSchema = z18.object({
2057
+ uri: z18.string(),
2058
+ title: z18.string(),
2059
+ domain: z18.string(),
2060
+ isOurDomain: z18.boolean(),
2061
+ isCompetitor: z18.boolean(),
2062
+ citationCount: z18.number().int().nonnegative(),
2063
+ providers: z18.array(providerNameSchema)
2064
+ });
2065
+ var contentSourceRowDtoSchema = z18.object({
2066
+ query: z18.string(),
2067
+ groundingSources: z18.array(contentGroundingSourceSchema)
2068
+ });
2069
+ var contentSourcesResponseDtoSchema = z18.object({
2070
+ sources: z18.array(contentSourceRowDtoSchema),
2071
+ latestRunId: z18.string()
2072
+ });
2073
+ var contentGapRowDtoSchema = z18.object({
2074
+ query: z18.string(),
2075
+ competitorDomains: z18.array(z18.string()),
2076
+ competitorCount: z18.number().int().nonnegative(),
2077
+ missRate: z18.number().min(0).max(1),
2078
+ lastSeenInRunId: z18.string()
2079
+ });
2080
+ var contentGapsResponseDtoSchema = z18.object({
2081
+ gaps: z18.array(contentGapRowDtoSchema),
2082
+ latestRunId: z18.string()
1862
2083
  });
1863
2084
 
1864
2085
  // ../contracts/src/doctor.ts
1865
- import { z as z17 } from "zod";
1866
- var checkStatusSchema = z17.enum(["ok", "warn", "fail", "skipped"]);
2086
+ import { z as z19 } from "zod";
2087
+ var checkStatusSchema = z19.enum(["ok", "warn", "fail", "skipped"]);
1867
2088
  var CheckStatuses = checkStatusSchema.enum;
1868
- var checkScopeSchema = z17.enum(["global", "project"]);
2089
+ var checkScopeSchema = z19.enum(["global", "project"]);
1869
2090
  var CheckScopes = checkScopeSchema.enum;
1870
- var checkCategorySchema = z17.enum([
2091
+ var checkCategorySchema = z19.enum([
1871
2092
  "auth",
1872
2093
  "config",
1873
2094
  "providers",
@@ -1878,31 +2099,31 @@ var checkCategorySchema = z17.enum([
1878
2099
  "agent"
1879
2100
  ]);
1880
2101
  var CheckCategories = checkCategorySchema.enum;
1881
- var checkResultSchema = z17.object({
1882
- id: z17.string(),
2102
+ var checkResultSchema = z19.object({
2103
+ id: z19.string(),
1883
2104
  category: checkCategorySchema,
1884
2105
  scope: checkScopeSchema,
1885
- title: z17.string(),
2106
+ title: z19.string(),
1886
2107
  status: checkStatusSchema,
1887
- code: z17.string().describe('Stable machine-readable code (e.g. "google.token.refresh-failed"). Use this for filtering and remediation logic.'),
1888
- summary: z17.string(),
1889
- remediation: z17.string().nullable().optional().describe('Operator-facing next step. Null when status is "ok" or no specific remediation applies.'),
1890
- details: z17.record(z17.string(), z17.unknown()).optional().describe("Structured context \u2014 principal email, redirect URI, missing scopes, etc. Stable per check id."),
1891
- durationMs: z17.number().int().nonnegative().describe("How long the check took to execute.")
2108
+ code: z19.string().describe('Stable machine-readable code (e.g. "google.token.refresh-failed"). Use this for filtering and remediation logic.'),
2109
+ summary: z19.string(),
2110
+ remediation: z19.string().nullable().optional().describe('Operator-facing next step. Null when status is "ok" or no specific remediation applies.'),
2111
+ details: z19.record(z19.string(), z19.unknown()).optional().describe("Structured context \u2014 principal email, redirect URI, missing scopes, etc. Stable per check id."),
2112
+ durationMs: z19.number().int().nonnegative().describe("How long the check took to execute.")
1892
2113
  });
1893
- var doctorReportSchema = z17.object({
2114
+ var doctorReportSchema = z19.object({
1894
2115
  scope: checkScopeSchema,
1895
- project: z17.string().nullable().describe('Project name when scope is "project", null otherwise.'),
1896
- generatedAt: z17.string().describe("ISO-8601 timestamp when this doctor run started."),
1897
- durationMs: z17.number().int().nonnegative(),
1898
- summary: z17.object({
1899
- total: z17.number().int().nonnegative(),
1900
- ok: z17.number().int().nonnegative(),
1901
- warn: z17.number().int().nonnegative(),
1902
- fail: z17.number().int().nonnegative(),
1903
- skipped: z17.number().int().nonnegative()
2116
+ project: z19.string().nullable().describe('Project name when scope is "project", null otherwise.'),
2117
+ generatedAt: z19.string().describe("ISO-8601 timestamp when this doctor run started."),
2118
+ durationMs: z19.number().int().nonnegative(),
2119
+ summary: z19.object({
2120
+ total: z19.number().int().nonnegative(),
2121
+ ok: z19.number().int().nonnegative(),
2122
+ warn: z19.number().int().nonnegative(),
2123
+ fail: z19.number().int().nonnegative(),
2124
+ skipped: z19.number().int().nonnegative()
1904
2125
  }),
1905
- checks: z17.array(checkResultSchema)
2126
+ checks: z19.array(checkResultSchema)
1906
2127
  });
1907
2128
  function summarizeCheckResults(results) {
1908
2129
  const summary = { total: results.length, ok: 0, warn: 0, fail: 0, skipped: 0 };
@@ -2048,52 +2269,52 @@ function normalizeUrlPath(input) {
2048
2269
  }
2049
2270
 
2050
2271
  // ../contracts/src/citations.ts
2051
- import { z as z18 } from "zod";
2052
- var citationCoverageProviderSchema = z18.object({
2053
- provider: z18.string(),
2272
+ import { z as z20 } from "zod";
2273
+ var citationCoverageProviderSchema = z20.object({
2274
+ provider: z20.string(),
2054
2275
  citationState: citationStateSchema,
2055
- cited: z18.boolean(),
2056
- mentioned: z18.boolean(),
2057
- runId: z18.string(),
2058
- runCreatedAt: z18.string()
2059
- });
2060
- var citationCoverageRowSchema = z18.object({
2061
- queryId: z18.string(),
2062
- query: z18.string(),
2063
- providers: z18.array(citationCoverageProviderSchema),
2064
- citedCount: z18.number().int().nonnegative(),
2065
- mentionedCount: z18.number().int().nonnegative(),
2066
- totalProviders: z18.number().int().nonnegative()
2276
+ cited: z20.boolean(),
2277
+ mentioned: z20.boolean(),
2278
+ runId: z20.string(),
2279
+ runCreatedAt: z20.string()
2280
+ });
2281
+ var citationCoverageRowSchema = z20.object({
2282
+ queryId: z20.string(),
2283
+ query: z20.string(),
2284
+ providers: z20.array(citationCoverageProviderSchema),
2285
+ citedCount: z20.number().int().nonnegative(),
2286
+ mentionedCount: z20.number().int().nonnegative(),
2287
+ totalProviders: z20.number().int().nonnegative()
2288
+ });
2289
+ var competitorGapRowSchema = z20.object({
2290
+ queryId: z20.string(),
2291
+ query: z20.string(),
2292
+ provider: z20.string(),
2293
+ citingCompetitors: z20.array(z20.string()),
2294
+ runId: z20.string(),
2295
+ runCreatedAt: z20.string()
2067
2296
  });
2068
- var competitorGapRowSchema = z18.object({
2069
- queryId: z18.string(),
2070
- query: z18.string(),
2071
- provider: z18.string(),
2072
- citingCompetitors: z18.array(z18.string()),
2073
- runId: z18.string(),
2074
- runCreatedAt: z18.string()
2075
- });
2076
- var citationVisibilitySummarySchema = z18.object({
2077
- providersConfigured: z18.number().int().nonnegative(),
2078
- providersCiting: z18.number().int().nonnegative(),
2079
- providersMentioning: z18.number().int().nonnegative(),
2080
- totalQueries: z18.number().int().nonnegative(),
2297
+ var citationVisibilitySummarySchema = z20.object({
2298
+ providersConfigured: z20.number().int().nonnegative(),
2299
+ providersCiting: z20.number().int().nonnegative(),
2300
+ providersMentioning: z20.number().int().nonnegative(),
2301
+ totalQueries: z20.number().int().nonnegative(),
2081
2302
  // Cross-tab buckets — each tracked query with at least one snapshot lands
2082
2303
  // in exactly one of these. Queries with zero snapshots are not counted in
2083
2304
  // any bucket; (sum of buckets) ≤ totalQueries.
2084
- queriesCitedAndMentioned: z18.number().int().nonnegative(),
2085
- queriesCitedOnly: z18.number().int().nonnegative(),
2086
- queriesMentionedOnly: z18.number().int().nonnegative(),
2087
- queriesInvisible: z18.number().int().nonnegative(),
2088
- latestRunId: z18.string().nullable(),
2089
- latestRunAt: z18.string().nullable()
2090
- });
2091
- var citationVisibilityResponseSchema = z18.object({
2305
+ queriesCitedAndMentioned: z20.number().int().nonnegative(),
2306
+ queriesCitedOnly: z20.number().int().nonnegative(),
2307
+ queriesMentionedOnly: z20.number().int().nonnegative(),
2308
+ queriesInvisible: z20.number().int().nonnegative(),
2309
+ latestRunId: z20.string().nullable(),
2310
+ latestRunAt: z20.string().nullable()
2311
+ });
2312
+ var citationVisibilityResponseSchema = z20.object({
2092
2313
  summary: citationVisibilitySummarySchema,
2093
- byQuery: z18.array(citationCoverageRowSchema),
2094
- competitorGaps: z18.array(competitorGapRowSchema),
2095
- status: z18.enum(["ready", "no-data"]),
2096
- reason: z18.enum(["no-runs-yet", "no-queries"]).optional()
2314
+ byQuery: z20.array(citationCoverageRowSchema),
2315
+ competitorGaps: z20.array(competitorGapRowSchema),
2316
+ status: z20.enum(["ready", "no-data"]),
2317
+ reason: z20.enum(["no-runs-yet", "no-queries"]).optional()
2097
2318
  });
2098
2319
  function emptyCitationVisibility(reason) {
2099
2320
  return {
@@ -2120,6 +2341,556 @@ function citationStateToCited(state) {
2120
2341
  }
2121
2342
 
2122
2343
  // ../contracts/src/report.ts
2344
+ import { z as z21 } from "zod";
2345
+ var providerLocationTreatmentSchema = z21.enum([
2346
+ "prompt",
2347
+ "request-param",
2348
+ "browser-geo",
2349
+ "ignored"
2350
+ ]);
2351
+ var reportMetaLocationSchema = z21.object({
2352
+ /** Human-readable label as configured on the project (e.g. "michigan"). */
2353
+ label: z21.string(),
2354
+ /** Resolved city/region/country from the project's `LocationContext`. */
2355
+ city: z21.string(),
2356
+ region: z21.string(),
2357
+ country: z21.string(),
2358
+ /**
2359
+ * Other locations configured on the project that did NOT power this report.
2360
+ * When non-empty, callers should make clear that the report is location-scoped:
2361
+ * a separate sweep is needed to see how AI engines respond from each one.
2362
+ */
2363
+ otherConfiguredLabels: z21.array(z21.string())
2364
+ });
2365
+ var reportProviderLocationHandlingSchema = z21.object({
2366
+ /** Provider name (matches `query_snapshots.provider`). */
2367
+ provider: z21.string(),
2368
+ /** How this provider applied the configured location during this run. */
2369
+ treatment: providerLocationTreatmentSchema,
2370
+ /** One-sentence explanation suitable for the report. */
2371
+ description: z21.string()
2372
+ });
2373
+ var reportMetaSchema = z21.object({
2374
+ /** ISO timestamp the report was generated (server clock). */
2375
+ generatedAt: z21.string(),
2376
+ /** Project the report covers. */
2377
+ project: z21.object({
2378
+ id: z21.string(),
2379
+ name: z21.string(),
2380
+ displayName: z21.string(),
2381
+ canonicalDomain: z21.string(),
2382
+ country: z21.string(),
2383
+ language: z21.string()
2384
+ }),
2385
+ /**
2386
+ * The location that powered the latest visibility run, when one was set.
2387
+ * `null` means the run had no location attached — providers received the
2388
+ * query verbatim with no geographic hint.
2389
+ */
2390
+ location: reportMetaLocationSchema.nullable(),
2391
+ /**
2392
+ * Per-provider location handling for the providers that ran in the latest
2393
+ * visibility sweep. Empty when there were no providers (or no run). Use
2394
+ * this to tell the reader whether the configured location actually shaped
2395
+ * each provider's answer — some providers append it to the prompt, some
2396
+ * pass it as a structured request field, and some (CDP) ignore it.
2397
+ */
2398
+ providerLocationHandling: z21.array(reportProviderLocationHandlingSchema),
2399
+ /** Earliest data point referenced by the report (ISO date). */
2400
+ periodStart: z21.string().nullable(),
2401
+ /** Latest data point referenced by the report (ISO date). */
2402
+ periodEnd: z21.string().nullable()
2403
+ });
2404
+ var reportExecutiveSummarySchema = z21.object({
2405
+ /**
2406
+ * 0..100 — share of tracked queries that were cited by at least one
2407
+ * provider in the latest run. "Cited" means the project's domain appeared
2408
+ * in the source list / grounding the AI used to answer. Computed per-query
2409
+ * (not per-(query × provider)) so the rate is invariant to provider count.
2410
+ */
2411
+ citationRate: z21.number(),
2412
+ /** Numerator of `citationRate` — distinct tracked queries cited by ≥1 provider in the latest run. */
2413
+ citedQueryCount: z21.number(),
2414
+ /** Denominator of `citationRate` — total tracked queries. */
2415
+ totalQueryCount: z21.number(),
2416
+ /**
2417
+ * 0..100 — share of tracked queries where the project's brand or domain
2418
+ * appeared in at least one provider's answer text in the latest run.
2419
+ * "Mentioned" is independent from "cited": a model can mention you in
2420
+ * the prose without citing your domain in its sources, and vice versa.
2421
+ * Same per-query denominator as `citationRate` for consistency.
2422
+ */
2423
+ mentionRate: z21.number(),
2424
+ /** Numerator of `mentionRate` — distinct tracked queries mentioned in ≥1 provider's answer text. */
2425
+ mentionedQueryCount: z21.number(),
2426
+ /** Compared to the previous run: 'up' | 'down' | 'flat' | 'unknown' (no prior run). */
2427
+ trend: z21.enum(["up", "down", "flat", "unknown"]),
2428
+ /** Total tracked queries. */
2429
+ queryCount: z21.number(),
2430
+ /** Total tracked competitors. */
2431
+ competitorCount: z21.number(),
2432
+ /** Number of providers in the latest run. */
2433
+ providerCount: z21.number(),
2434
+ /** GSC totals across the most-recent sync window. Null when GSC is not connected. */
2435
+ gsc: z21.object({
2436
+ clicks: z21.number(),
2437
+ impressions: z21.number(),
2438
+ ctr: z21.number(),
2439
+ avgPosition: z21.number(),
2440
+ periodStart: z21.string(),
2441
+ periodEnd: z21.string()
2442
+ }).nullable(),
2443
+ /** GA4 totals across the most-recent sync period. Null when GA4 is not connected. */
2444
+ ga: z21.object({
2445
+ sessions: z21.number(),
2446
+ users: z21.number(),
2447
+ periodStart: z21.string(),
2448
+ periodEnd: z21.string()
2449
+ }).nullable(),
2450
+ /** Top 3-5 findings, each rendered as a single-sentence narrative. */
2451
+ findings: z21.array(z21.object({
2452
+ title: z21.string(),
2453
+ detail: z21.string(),
2454
+ tone: z21.enum(["positive", "caution", "negative", "neutral"])
2455
+ }))
2456
+ });
2457
+ var citationCellSchema = z21.object({
2458
+ citationState: z21.enum(["cited", "not-cited", "pending"]),
2459
+ answerMentioned: z21.boolean().nullable(),
2460
+ model: z21.string().nullable()
2461
+ });
2462
+ var citationScorecardSchema = z21.object({
2463
+ queries: z21.array(z21.string()),
2464
+ providers: z21.array(z21.string()),
2465
+ /** matrix[queryIndex][providerIndex] — null when no snapshot exists for the pair. */
2466
+ matrix: z21.array(z21.array(citationCellSchema.nullable())),
2467
+ /** Per-provider citation rate (0..100). */
2468
+ providerRates: z21.array(z21.object({
2469
+ provider: z21.string(),
2470
+ citedCount: z21.number(),
2471
+ totalCount: z21.number(),
2472
+ citationRate: z21.number()
2473
+ }))
2474
+ });
2475
+ var competitorRowSchema = z21.object({
2476
+ domain: z21.string(),
2477
+ /** Number of (query × provider) pairs that cited this competitor. */
2478
+ citationCount: z21.number(),
2479
+ /** Out-of count for the same denominator. */
2480
+ totalCount: z21.number(),
2481
+ /** 'High' | 'Moderate' | 'Low' | 'None' — from buildPortfolioProject pressure logic. */
2482
+ pressureLabel: z21.enum(["High", "Moderate", "Low", "None"]),
2483
+ /** Distinct queries on which this competitor was cited. */
2484
+ citedQueries: z21.array(z21.string()),
2485
+ /**
2486
+ * Citation share 0..100. Numerator = this competitor's `citationCount`.
2487
+ * Denominator = sum of `citationCount` across all competitors plus the
2488
+ * project's own `projectCitationCount`. Equals 0 when there are no cited
2489
+ * slots in the snapshot. Distinct from the project-level Mention Share
2490
+ * gauge — that one is brand-in-answer-text, this one is domain-in-source-list.
2491
+ */
2492
+ sharePct: z21.number(),
2493
+ /**
2494
+ * URLs from the latest run's grounding sources whose host matches this
2495
+ * competitor's domain, with the queries each URL was cited for. Empty
2496
+ * when no grounding-source data is available (e.g. no `rawResponse` JSON
2497
+ * stored for the snapshots).
2498
+ */
2499
+ theirCitedPages: z21.array(z21.object({ url: z21.string(), citedFor: z21.array(z21.string()) }))
2500
+ });
2501
+ var competitorLandscapeSchema = z21.object({
2502
+ /** Project's own citation count (for the bar chart comparing project vs competitors). */
2503
+ projectCitationCount: z21.number(),
2504
+ competitors: z21.array(competitorRowSchema)
2505
+ });
2506
+ var mentionRowSchema = z21.object({
2507
+ domain: z21.string(),
2508
+ /** Number of (query × provider) pairs whose answer text mentioned this competitor's brand or domain. */
2509
+ mentionCount: z21.number(),
2510
+ /** Out-of count for the same denominator (snapshots that had answer text). */
2511
+ totalCount: z21.number(),
2512
+ /** 'High' | 'Moderate' | 'Low' | 'None' — mention frequency tier (mirrors CompetitorRow.pressureLabel). */
2513
+ pressureLabel: z21.enum(["High", "Moderate", "Low", "None"]),
2514
+ /** Distinct queries on which this competitor was mentioned. */
2515
+ mentionedQueries: z21.array(z21.string()),
2516
+ /**
2517
+ * Mention share 0..100. Numerator = this competitor's `mentionCount`.
2518
+ * Denominator = sum of `mentionCount` across all competitors plus the
2519
+ * project's own `projectMentionCount`. Equals 0 when no snapshot had any
2520
+ * mention. Per-competitor split of the same head-to-head measure the
2521
+ * project's hero `MentionShareDto` gauge headlines.
2522
+ */
2523
+ sharePct: z21.number()
2524
+ });
2525
+ var mentionLandscapeSchema = z21.object({
2526
+ /** Project's own mention count (for the bar chart comparing project vs competitors). */
2527
+ projectMentionCount: z21.number(),
2528
+ /** Snapshots considered — those with non-empty answerText. Drives the totalCount denominator. */
2529
+ totalAnswerSnapshots: z21.number(),
2530
+ competitors: z21.array(mentionRowSchema)
2531
+ });
2532
+ var aiSourceCategoryBucketSchema = z21.object({
2533
+ /** Category slug from packages/contracts/src/source-categories. */
2534
+ category: z21.string(),
2535
+ /** Display label. */
2536
+ label: z21.string(),
2537
+ /** Number of citations falling in this category. */
2538
+ count: z21.number(),
2539
+ /** 0..100 share of total citations. */
2540
+ sharePct: z21.number()
2541
+ });
2542
+ var aiSourceOriginSchema = z21.object({
2543
+ categories: z21.array(aiSourceCategoryBucketSchema),
2544
+ /** Top 20 source domains by citation count (excluding the project's own domain). */
2545
+ topDomains: z21.array(z21.object({
2546
+ domain: z21.string(),
2547
+ count: z21.number(),
2548
+ /** True when the domain is one of the project's tracked competitors. */
2549
+ isCompetitor: z21.boolean()
2550
+ }))
2551
+ });
2552
+ var gscQueryRowSchema = z21.object({
2553
+ query: z21.string(),
2554
+ clicks: z21.number(),
2555
+ impressions: z21.number(),
2556
+ ctr: z21.number(),
2557
+ avgPosition: z21.number(),
2558
+ /** Heuristic categorization: 'brand' | 'lead-gen' | 'industry' | 'other'. */
2559
+ category: z21.enum(["brand", "lead-gen", "industry", "other"])
2560
+ });
2561
+ var gscSectionSchema = z21.object({
2562
+ periodStart: z21.string(),
2563
+ periodEnd: z21.string(),
2564
+ totalClicks: z21.number(),
2565
+ totalImpressions: z21.number(),
2566
+ ctr: z21.number(),
2567
+ avgPosition: z21.number(),
2568
+ topQueries: z21.array(gscQueryRowSchema),
2569
+ categoryBreakdown: z21.array(z21.object({
2570
+ category: z21.enum(["brand", "lead-gen", "industry", "other"]),
2571
+ clicks: z21.number(),
2572
+ impressions: z21.number(),
2573
+ sharePct: z21.number()
2574
+ })),
2575
+ trend: z21.array(z21.object({ date: z21.string(), clicks: z21.number(), impressions: z21.number() })),
2576
+ /**
2577
+ * Tracked AEO queries that have no GSC impressions in the report window.
2578
+ * Surfaces queries that may not represent real search demand.
2579
+ */
2580
+ trackedButNoGsc: z21.array(z21.string()),
2581
+ /**
2582
+ * GSC top queries (sorted by impressions desc) that are not tracked as
2583
+ * AEO queries — the candidate set for adding to the AEO project.
2584
+ */
2585
+ gscButNotTracked: z21.array(z21.string())
2586
+ });
2587
+ var gaTrafficSectionSchema = z21.object({
2588
+ totalSessions: z21.number(),
2589
+ totalUsers: z21.number(),
2590
+ totalOrganicSessions: z21.number(),
2591
+ periodStart: z21.string(),
2592
+ periodEnd: z21.string(),
2593
+ topLandingPages: z21.array(z21.object({
2594
+ page: z21.string(),
2595
+ sessions: z21.number(),
2596
+ users: z21.number(),
2597
+ organicSessions: z21.number()
2598
+ })),
2599
+ channelBreakdown: z21.array(z21.object({
2600
+ channel: z21.string(),
2601
+ sessions: z21.number(),
2602
+ sharePct: z21.number()
2603
+ }))
2604
+ });
2605
+ var socialReferralSectionSchema = z21.object({
2606
+ totalSessions: z21.number(),
2607
+ organicSessions: z21.number(),
2608
+ paidSessions: z21.number(),
2609
+ channels: z21.array(z21.object({
2610
+ channelGroup: z21.string(),
2611
+ sessions: z21.number(),
2612
+ sharePct: z21.number()
2613
+ })),
2614
+ topCampaigns: z21.array(z21.object({
2615
+ source: z21.string(),
2616
+ medium: z21.string(),
2617
+ sessions: z21.number()
2618
+ }))
2619
+ });
2620
+ var aiReferralSectionSchema = z21.object({
2621
+ totalSessions: z21.number(),
2622
+ totalUsers: z21.number(),
2623
+ bySource: z21.array(z21.object({
2624
+ source: z21.string(),
2625
+ sessions: z21.number(),
2626
+ users: z21.number(),
2627
+ sharePct: z21.number()
2628
+ })),
2629
+ trend: z21.array(z21.object({ date: z21.string(), sessions: z21.number() })),
2630
+ topLandingPages: z21.array(z21.object({
2631
+ page: z21.string(),
2632
+ sessions: z21.number(),
2633
+ users: z21.number()
2634
+ }))
2635
+ });
2636
+ var serverActivitySectionSchema = z21.object({
2637
+ /** ISO8601 inclusive lower bound of the report window (default: 7 days). */
2638
+ windowStart: z21.string(),
2639
+ /** ISO8601 inclusive upper bound. */
2640
+ windowEnd: z21.string(),
2641
+ hasData: z21.boolean(),
2642
+ /** Last-7d total verified crawler hits, with prior 7d for delta. */
2643
+ verifiedCrawlerHits: z21.object({ current: z21.number(), prior: z21.number(), deltaPct: z21.number().nullable() }),
2644
+ /** Last-7d total unverified crawler hits, separated from verified trust metrics. */
2645
+ unverifiedCrawlerHits: z21.object({ current: z21.number(), prior: z21.number(), deltaPct: z21.number().nullable() }),
2646
+ /** Last-7d AI-referral sessions (sessionized from server-side request evidence). */
2647
+ referralArrivals: z21.object({ current: z21.number(), prior: z21.number(), deltaPct: z21.number().nullable() }),
2648
+ /** Per-AI-operator breakdown (OpenAI, Anthropic, Google AI, Perplexity, …). */
2649
+ byOperator: z21.array(z21.object({
2650
+ operator: z21.string(),
2651
+ verifiedHits: z21.number(),
2652
+ /** Shown to agency audience only — claimed-bot UA, rDNS not confirmed. */
2653
+ unverifiedHits: z21.number(),
2654
+ referralArrivals: z21.number(),
2655
+ deltaPct: z21.number().nullable()
2656
+ })),
2657
+ /**
2658
+ * Top crawled paths (verified only, last-7d). Path-level citation cross-reference
2659
+ * is intentionally NOT included today — the citation store is domain-grain
2660
+ * (`query_snapshots.cited_domains` is a JSON array of hostnames), so a path-level
2661
+ * "cited?" flag would be misleading. A future iteration that lands URL-grain
2662
+ * citation evidence can extend this entry with a `citationState` field without
2663
+ * breaking the contract.
2664
+ */
2665
+ topCrawledPaths: z21.array(z21.object({
2666
+ path: z21.string(),
2667
+ verifiedHits: z21.number(),
2668
+ /** How many distinct AI operators crawled this path in the window. */
2669
+ distinctOperators: z21.number()
2670
+ })),
2671
+ /** AI products that sent ≥1 session in the window (referral by destination). */
2672
+ referralProducts: z21.array(z21.object({
2673
+ product: z21.string(),
2674
+ arrivals: z21.number(),
2675
+ distinctLandingPaths: z21.number()
2676
+ })),
2677
+ /** Daily trend, last 14d for sparkline / chart rendering. */
2678
+ dailyTrend: z21.array(z21.object({
2679
+ date: z21.string(),
2680
+ verifiedCrawlerHits: z21.number(),
2681
+ referralArrivals: z21.number()
2682
+ })),
2683
+ /**
2684
+ * Top landing paths for AI-referral sessions (last-7d).
2685
+ * Complements `topCrawledPaths` (what bots fetch) with what humans actually land on.
2686
+ */
2687
+ topReferralLandingPaths: z21.array(z21.object({
2688
+ path: z21.string(),
2689
+ arrivals: z21.number(),
2690
+ distinctProducts: z21.number()
2691
+ }))
2692
+ });
2693
+ var indexingHealthSectionSchema = z21.object({
2694
+ /** Source: 'google' | 'bing' | null when neither is connected. */
2695
+ provider: z21.enum(["google", "bing"]).nullable(),
2696
+ total: z21.number(),
2697
+ indexed: z21.number(),
2698
+ notIndexed: z21.number(),
2699
+ /** Google-only — pages explicitly marked as deindexed. Bing reports 'unknown' instead. */
2700
+ deindexed: z21.number(),
2701
+ /** Bing-only — pages with no inspection data yet. */
2702
+ unknown: z21.number(),
2703
+ /** 0..100. */
2704
+ indexedPct: z21.number()
2705
+ });
2706
+ var citationsTrendPointSchema = z21.object({
2707
+ /** Run ID — anchor for cross-section linking. */
2708
+ runId: z21.string(),
2709
+ /** ISO timestamp when the run finished (or createdAt fallback). */
2710
+ date: z21.string(),
2711
+ /**
2712
+ * 0..100 — same per-query unique-cited definition as
2713
+ * `ReportExecutiveSummary.citationRate`. Stable across runs with different
2714
+ * provider counts so the trend line measures real movement rather than
2715
+ * provider-count variance.
2716
+ */
2717
+ citationRate: z21.number(),
2718
+ /** Numerator of `citationRate` for this run. */
2719
+ citedQueryCount: z21.number(),
2720
+ /** Denominator of `citationRate` for this run. */
2721
+ totalQueryCount: z21.number(),
2722
+ /** 0..100 — same per-query unique-mentioned definition as `ReportExecutiveSummary.mentionRate`. */
2723
+ mentionRate: z21.number(),
2724
+ /** Numerator of `mentionRate` for this run. */
2725
+ mentionedQueryCount: z21.number(),
2726
+ /**
2727
+ * Per-provider rates for the same run. Each provider's rate is per-pair
2728
+ * within that provider (`cited / scanned`), so it remains comparable
2729
+ * between providers in the same run.
2730
+ */
2731
+ providerRates: z21.array(z21.object({ provider: z21.string(), citationRate: z21.number() }))
2732
+ });
2733
+ var reportInsightSchema = z21.object({
2734
+ id: z21.string(),
2735
+ type: z21.enum(["regression", "gain", "opportunity"]),
2736
+ severity: z21.enum(["critical", "high", "medium", "low"]),
2737
+ title: z21.string(),
2738
+ query: z21.string(),
2739
+ provider: z21.string(),
2740
+ recommendation: z21.string().nullable(),
2741
+ createdAt: z21.string(),
2742
+ /**
2743
+ * How many times this insight fired across recent runs for the same
2744
+ * `(query, provider, type)` tuple. Always ≥ 1. Insights returned by the
2745
+ * report API are already deduped to one row per tuple, with this counter
2746
+ * surfacing the multiplicity. Use it directly instead of grouping again
2747
+ * client-side — counts derived from raw insight rows will overcount.
2748
+ */
2749
+ instanceCount: z21.number()
2750
+ });
2751
+ var recommendedNextStepSchema = z21.object({
2752
+ /** 'immediate' | 'short-term' | 'medium-term' — bucketed by severity heuristic. */
2753
+ horizon: z21.enum(["immediate", "short-term", "medium-term"]),
2754
+ title: z21.string(),
2755
+ rationale: z21.string()
2756
+ });
2757
+ var reportRateDeltaSchema = z21.object({
2758
+ /** Current value (0..100 for rates, raw count otherwise). When `window`
2759
+ * is present this is the average over the last `window` checks. */
2760
+ current: z21.number(),
2761
+ /** Prior value compared against. When `window` is present this is the
2762
+ * average over the prior `window` checks before that. */
2763
+ prior: z21.number(),
2764
+ /** Absolute delta (current − prior). Negative = decrease. */
2765
+ deltaAbs: z21.number(),
2766
+ /**
2767
+ * Direction tag for tone mapping. Threshold is metric-specific (3pp for
2768
+ * rates, 0.5 for counts) so small noise lands as 'flat' rather than
2769
+ * flipping up/down each run.
2770
+ */
2771
+ direction: z21.enum(["up", "down", "flat"]),
2772
+ /**
2773
+ * How many points went into each side of the average. Omitted (or 1)
2774
+ * means point-to-point (legacy "since last check"). Higher values mean
2775
+ * a rolling-average comparison — renderers should label it as
2776
+ * "vs prior N checks" when this is ≥ 2.
2777
+ */
2778
+ window: z21.number().optional()
2779
+ });
2780
+ var reportProviderMovementSchema = z21.object({
2781
+ provider: z21.string(),
2782
+ current: z21.number(),
2783
+ prior: z21.number(),
2784
+ deltaAbs: z21.number(),
2785
+ direction: z21.enum(["up", "down", "flat"])
2786
+ });
2787
+ var whatsChangedSectionSchema = z21.object({
2788
+ /**
2789
+ * False when there's no prior run (or fewer than the trend baseline),
2790
+ * meaning all per-metric deltas will be null. Renderers use this to swap
2791
+ * in a "establishing baseline" fallback rather than rendering empty
2792
+ * delta tiles.
2793
+ */
2794
+ enoughHistory: z21.boolean(),
2795
+ /**
2796
+ * One-sentence narrative summary suitable as a section subtitle.
2797
+ * Always present — even on baseline, narrates whatever signal exists.
2798
+ */
2799
+ headline: z21.string(),
2800
+ /** Citation rate delta vs the prior completed run. Null when no prior run. */
2801
+ citationRate: reportRateDeltaSchema.nullable(),
2802
+ /** Mention rate delta vs the prior completed run. Null when no prior run. */
2803
+ mentionRate: reportRateDeltaSchema.nullable(),
2804
+ /** Cited query count delta vs the prior completed run. Null when no prior run. */
2805
+ citedQueryCount: reportRateDeltaSchema.nullable(),
2806
+ /**
2807
+ * GSC clicks delta — last 14 days of `gsc.trend` vs the 14 days before
2808
+ * that. Null when GSC isn't connected or fewer than 28 trend points exist.
2809
+ */
2810
+ gscClicksDelta: reportRateDeltaSchema.nullable(),
2811
+ /**
2812
+ * AI referral sessions delta — last 14 days of `aiReferrals.trend` vs the
2813
+ * 14 days before that. Null when AI referrals aren't tracked or fewer
2814
+ * than 28 trend points exist.
2815
+ */
2816
+ aiReferralsDelta: reportRateDeltaSchema.nullable(),
2817
+ /**
2818
+ * Per-provider citation rate movements (latest run vs prior run). Empty
2819
+ * when no prior run. Sorted by |deltaAbs| desc — providers with the
2820
+ * biggest swing first.
2821
+ */
2822
+ providerMovements: z21.array(reportProviderMovementSchema),
2823
+ /**
2824
+ * Top wins this period — gains surfaced by the intelligence engine.
2825
+ * Capped at 5; sourced from `insights` filtered to `type: 'gain'`.
2826
+ */
2827
+ wins: z21.array(reportInsightSchema),
2828
+ /**
2829
+ * Top regressions this period — citations or mentions lost. Capped at 5;
2830
+ * sourced from `insights` filtered to `type: 'regression'`.
2831
+ */
2832
+ regressions: z21.array(reportInsightSchema)
2833
+ });
2834
+ var reportAudienceSchema = z21.enum(["agency", "client"]);
2835
+ var reportActionAudienceSchema = z21.enum(["agency", "client", "both"]);
2836
+ var reportActionHorizonSchema = z21.enum(["immediate", "short-term", "medium-term"]);
2837
+ var reportActionConfidenceSchema = z21.enum(["high", "medium", "low"]);
2838
+ var reportToneSchema = z21.enum(["positive", "caution", "negative", "neutral"]);
2839
+ var reportActionCategorySchema = z21.enum([
2840
+ "content",
2841
+ "competitors",
2842
+ "provider",
2843
+ "search-demand",
2844
+ "indexing",
2845
+ "location",
2846
+ "monitoring"
2847
+ ]);
2848
+ var reportActionPlanItemSchema = z21.object({
2849
+ /** Which report audience should see this action. `both` renders in both modes. */
2850
+ audience: reportActionAudienceSchema,
2851
+ /** Stable sort priority. Lower numbers render earlier. */
2852
+ priority: z21.number(),
2853
+ /** When this should be tackled. */
2854
+ horizon: reportActionHorizonSchema,
2855
+ category: reportActionCategorySchema,
2856
+ title: z21.string(),
2857
+ /** Direct next step written as an operator/client-friendly imperative. */
2858
+ action: z21.string(),
2859
+ /** Why this matters. Keep each entry concise and evidence-backed. */
2860
+ why: z21.array(z21.string()),
2861
+ /** Specific observations that justify the action. */
2862
+ evidence: z21.array(z21.string()),
2863
+ /** What should move if the action worked. */
2864
+ successMetric: z21.string(),
2865
+ /** Confidence in the recommendation based on the available evidence. */
2866
+ confidence: reportActionConfidenceSchema,
2867
+ /**
2868
+ * Stable hash from the underlying content opportunity, present only when
2869
+ * the action was derived from `contentOpportunities` (the
2870
+ * `ContentTargetRowDto.targetRef` value). UI surfaces a "Mark addressed"
2871
+ * button on actions that carry one — clicking it persists a dismissal in
2872
+ * `content_target_dismissals` and the action drops off the next report
2873
+ * load. Actions sourced from other signals (competitor gaps, indexing
2874
+ * issues, etc.) omit this and use their own dismiss flows.
2875
+ */
2876
+ targetRef: z21.string().optional()
2877
+ });
2878
+ var reportClientSummarySchema = z21.object({
2879
+ headline: z21.string(),
2880
+ overview: z21.string(),
2881
+ actionItems: z21.array(reportActionPlanItemSchema),
2882
+ confidenceNotes: z21.array(z21.string())
2883
+ });
2884
+ var reportAgencyDiagnosticSchema = z21.object({
2885
+ title: z21.string(),
2886
+ detail: z21.string(),
2887
+ severity: z21.enum(["positive", "caution", "negative", "neutral"]),
2888
+ evidence: z21.array(z21.string())
2889
+ });
2890
+ var reportAgencyDiagnosticsSchema = z21.object({
2891
+ priorities: z21.array(reportActionPlanItemSchema),
2892
+ diagnostics: z21.array(reportAgencyDiagnosticSchema)
2893
+ });
2123
2894
  function reportActionTone(action) {
2124
2895
  if (action.horizon === "immediate") return "negative";
2125
2896
  if (action.confidence === "high") return "caution";
@@ -2176,6 +2947,51 @@ function reportConfidenceLabel(confidence) {
2176
2947
  return "Low";
2177
2948
  }
2178
2949
  }
2950
+ var projectReportDtoSchema = z21.object({
2951
+ meta: reportMetaSchema,
2952
+ executiveSummary: reportExecutiveSummarySchema,
2953
+ citationScorecard: citationScorecardSchema,
2954
+ competitorLandscape: competitorLandscapeSchema,
2955
+ mentionLandscape: mentionLandscapeSchema,
2956
+ aiSourceOrigin: aiSourceOriginSchema,
2957
+ gsc: gscSectionSchema.nullable(),
2958
+ ga: gaTrafficSectionSchema.nullable(),
2959
+ socialReferrals: socialReferralSectionSchema.nullable(),
2960
+ aiReferrals: aiReferralSectionSchema.nullable(),
2961
+ /** Server-side log-evidence visibility (crawls + click-through sessions). Null when no traffic source connected. */
2962
+ serverActivity: serverActivitySectionSchema.nullable(),
2963
+ indexingHealth: indexingHealthSectionSchema.nullable(),
2964
+ citationsTrend: z21.array(citationsTrendPointSchema),
2965
+ /**
2966
+ * Trend-focused "what's changed" summary for the report's act 2. Always
2967
+ * present; renderers gate empty/baseline states via `enoughHistory`.
2968
+ */
2969
+ whatsChanged: whatsChangedSectionSchema,
2970
+ insights: z21.array(reportInsightSchema),
2971
+ recommendedNextSteps: z21.array(recommendedNextStepSchema),
2972
+ /** Canonical structured actions shared by the client and agency render modes. */
2973
+ actionPlan: z21.array(reportActionPlanItemSchema),
2974
+ /** Polished client-facing summary and action shortlist. */
2975
+ clientSummary: reportClientSummarySchema,
2976
+ /** Technical, evidence-oriented operator diagnostics for agency mode. */
2977
+ agencyDiagnostics: reportAgencyDiagnosticsSchema,
2978
+ /**
2979
+ * Ranked, action-typed content opportunities sourced from the existing
2980
+ * intelligence layer (`buildContentTargetRows`). Empty when no run has
2981
+ * produced candidate queries with demand or competitor signal.
2982
+ */
2983
+ contentOpportunities: z21.array(contentTargetRowDtoSchema),
2984
+ /**
2985
+ * Queries where competitors were cited but the project was not. Sourced
2986
+ * from `buildContentGapRows`. Empty until the first answer-visibility run.
2987
+ */
2988
+ contentGaps: z21.array(contentGapRowDtoSchema),
2989
+ /**
2990
+ * Per-query grounding source map (own + competitor cited URLs). Sourced
2991
+ * from `buildContentSourceRows`. Empty until the first answer-visibility run.
2992
+ */
2993
+ groundingSources: z21.array(contentSourceRowDtoSchema)
2994
+ });
2179
2995
 
2180
2996
  // ../contracts/src/report-dedup.ts
2181
2997
  var REPORT_INTENT_STOPWORDS = /* @__PURE__ */ new Set([
@@ -2245,15 +3061,15 @@ function dedupeReportOpportunities(report) {
2245
3061
  }
2246
3062
 
2247
3063
  // ../contracts/src/skills.ts
2248
- import { z as z19 } from "zod";
2249
- var codingAgentSchema = z19.enum(["claude", "codex"]);
3064
+ import { z as z22 } from "zod";
3065
+ var codingAgentSchema = z22.enum(["claude", "codex"]);
2250
3066
  var CodingAgents = codingAgentSchema.enum;
2251
- var skillsClientSchema = z19.enum(["claude", "codex", "all"]);
3067
+ var skillsClientSchema = z22.enum(["claude", "codex", "all"]);
2252
3068
  var SkillsClients = skillsClientSchema.enum;
2253
3069
 
2254
3070
  // ../contracts/src/traffic.ts
2255
- import { z as z20 } from "zod";
2256
- var trafficSourceTypeSchema = z20.enum([
3071
+ import { z as z23 } from "zod";
3072
+ var trafficSourceTypeSchema = z23.enum([
2257
3073
  "cloud-run",
2258
3074
  "wordpress",
2259
3075
  "cloudflare",
@@ -2261,7 +3077,7 @@ var trafficSourceTypeSchema = z20.enum([
2261
3077
  "generic-log"
2262
3078
  ]);
2263
3079
  var TrafficSourceTypes = trafficSourceTypeSchema.enum;
2264
- var trafficAdapterCapabilitySchema = z20.enum([
3080
+ var trafficAdapterCapabilitySchema = z23.enum([
2265
3081
  "raw-request-events",
2266
3082
  "aggregate-request-metrics",
2267
3083
  "request-url",
@@ -2272,198 +3088,198 @@ var trafficAdapterCapabilitySchema = z20.enum([
2272
3088
  "cursor-pull"
2273
3089
  ]);
2274
3090
  var TrafficAdapterCapabilities = trafficAdapterCapabilitySchema.enum;
2275
- var trafficEvidenceKindSchema = z20.enum(["raw-request", "aggregate-bucket"]);
3091
+ var trafficEvidenceKindSchema = z23.enum(["raw-request", "aggregate-bucket"]);
2276
3092
  var TrafficEvidenceKinds = trafficEvidenceKindSchema.enum;
2277
- var trafficEventConfidenceSchema = z20.enum(["observed", "provider-aggregated", "inferred"]);
3093
+ var trafficEventConfidenceSchema = z23.enum(["observed", "provider-aggregated", "inferred"]);
2278
3094
  var TrafficEventConfidences = trafficEventConfidenceSchema.enum;
2279
- var trafficProviderResourceSchema = z20.object({
2280
- type: z20.string().nullable(),
2281
- labels: z20.record(z20.string(), z20.string())
3095
+ var trafficProviderResourceSchema = z23.object({
3096
+ type: z23.string().nullable(),
3097
+ labels: z23.record(z23.string(), z23.string())
2282
3098
  });
2283
- var normalizedTrafficRequestSchema = z20.object({
3099
+ var normalizedTrafficRequestSchema = z23.object({
2284
3100
  sourceType: trafficSourceTypeSchema,
2285
- evidenceKind: z20.literal(TrafficEvidenceKinds["raw-request"]),
2286
- confidence: z20.literal(TrafficEventConfidences.observed),
2287
- eventId: z20.string().min(1),
2288
- observedAt: z20.string().min(1),
2289
- method: z20.string().nullable(),
2290
- requestUrl: z20.string().nullable(),
2291
- host: z20.string().nullable(),
2292
- path: z20.string().min(1),
2293
- queryString: z20.string().nullable(),
2294
- status: z20.number().int().nullable(),
2295
- userAgent: z20.string().nullable(),
2296
- remoteIp: z20.string().nullable(),
2297
- referer: z20.string().nullable(),
2298
- latencyMs: z20.number().nullable(),
2299
- requestSizeBytes: z20.number().int().nullable(),
2300
- responseSizeBytes: z20.number().int().nullable(),
3101
+ evidenceKind: z23.literal(TrafficEvidenceKinds["raw-request"]),
3102
+ confidence: z23.literal(TrafficEventConfidences.observed),
3103
+ eventId: z23.string().min(1),
3104
+ observedAt: z23.string().min(1),
3105
+ method: z23.string().nullable(),
3106
+ requestUrl: z23.string().nullable(),
3107
+ host: z23.string().nullable(),
3108
+ path: z23.string().min(1),
3109
+ queryString: z23.string().nullable(),
3110
+ status: z23.number().int().nullable(),
3111
+ userAgent: z23.string().nullable(),
3112
+ remoteIp: z23.string().nullable(),
3113
+ referer: z23.string().nullable(),
3114
+ latencyMs: z23.number().nullable(),
3115
+ requestSizeBytes: z23.number().int().nullable(),
3116
+ responseSizeBytes: z23.number().int().nullable(),
2301
3117
  providerResource: trafficProviderResourceSchema,
2302
- providerLabels: z20.record(z20.string(), z20.string())
3118
+ providerLabels: z23.record(z23.string(), z23.string())
2303
3119
  });
2304
- var normalizedTrafficPullPageSchema = z20.object({
2305
- events: z20.array(normalizedTrafficRequestSchema),
2306
- rawEntryCount: z20.number().int().nonnegative(),
2307
- skippedEntryCount: z20.number().int().nonnegative(),
2308
- nextPageToken: z20.string().optional(),
2309
- filter: z20.string()
3120
+ var normalizedTrafficPullPageSchema = z23.object({
3121
+ events: z23.array(normalizedTrafficRequestSchema),
3122
+ rawEntryCount: z23.number().int().nonnegative(),
3123
+ skippedEntryCount: z23.number().int().nonnegative(),
3124
+ nextPageToken: z23.string().optional(),
3125
+ filter: z23.string()
2310
3126
  });
2311
- var trafficSourceStatusSchema = z20.enum(["connected", "paused", "error", "archived"]);
3127
+ var trafficSourceStatusSchema = z23.enum(["connected", "paused", "error", "archived"]);
2312
3128
  var TrafficSourceStatuses = trafficSourceStatusSchema.enum;
2313
- var trafficSourceAuthModeSchema = z20.enum(["oauth", "service-account"]);
3129
+ var trafficSourceAuthModeSchema = z23.enum(["oauth", "service-account"]);
2314
3130
  var TrafficSourceAuthModes = trafficSourceAuthModeSchema.enum;
2315
- var verificationStatusSchema = z20.enum(["verified", "claimed_unverified", "unknown_ai_like"]);
3131
+ var verificationStatusSchema = z23.enum(["verified", "claimed_unverified", "unknown_ai_like"]);
2316
3132
  var VerificationStatuses = verificationStatusSchema.enum;
2317
- var cloudRunSourceConfigSchema = z20.object({
2318
- gcpProjectId: z20.string().min(1),
2319
- serviceName: z20.string().nullable().optional(),
2320
- location: z20.string().nullable().optional(),
3133
+ var cloudRunSourceConfigSchema = z23.object({
3134
+ gcpProjectId: z23.string().min(1),
3135
+ serviceName: z23.string().nullable().optional(),
3136
+ location: z23.string().nullable().optional(),
2321
3137
  authMode: trafficSourceAuthModeSchema
2322
3138
  });
2323
- var wordpressTrafficSourceConfigSchema = z20.object({
2324
- baseUrl: z20.string().url(),
2325
- username: z20.string().min(1)
3139
+ var wordpressTrafficSourceConfigSchema = z23.object({
3140
+ baseUrl: z23.string().url(),
3141
+ username: z23.string().min(1)
2326
3142
  });
2327
- var vercelTrafficEnvironmentSchema = z20.enum(["production", "preview"]);
3143
+ var vercelTrafficEnvironmentSchema = z23.enum(["production", "preview"]);
2328
3144
  var VercelTrafficEnvironments = vercelTrafficEnvironmentSchema.enum;
2329
- var vercelTrafficSourceConfigSchema = z20.object({
3145
+ var vercelTrafficSourceConfigSchema = z23.object({
2330
3146
  /** Vercel project id (e.g. `prj_...`). */
2331
- projectId: z20.string().min(1),
3147
+ projectId: z23.string().min(1),
2332
3148
  /** Vercel team / owner id (e.g. `team_...`). */
2333
- teamId: z20.string().min(1),
3149
+ teamId: z23.string().min(1),
2334
3150
  environment: vercelTrafficEnvironmentSchema
2335
3151
  });
2336
- var trafficSourceDtoSchema = z20.object({
2337
- id: z20.string(),
2338
- projectId: z20.string(),
3152
+ var trafficSourceDtoSchema = z23.object({
3153
+ id: z23.string(),
3154
+ projectId: z23.string(),
2339
3155
  sourceType: trafficSourceTypeSchema,
2340
- displayName: z20.string(),
3156
+ displayName: z23.string(),
2341
3157
  status: trafficSourceStatusSchema,
2342
- lastSyncedAt: z20.string().nullable(),
2343
- lastCursor: z20.string().nullable(),
2344
- lastError: z20.string().nullable(),
2345
- archivedAt: z20.string().nullable(),
2346
- config: z20.record(z20.string(), z20.unknown()),
2347
- createdAt: z20.string(),
2348
- updatedAt: z20.string()
2349
- });
2350
- var trafficConnectCloudRunRequestSchema = z20.object({
2351
- gcpProjectId: z20.string().min(1),
2352
- serviceName: z20.string().min(1).optional(),
2353
- location: z20.string().min(1).optional(),
2354
- displayName: z20.string().min(1).optional(),
3158
+ lastSyncedAt: z23.string().nullable(),
3159
+ lastCursor: z23.string().nullable(),
3160
+ lastError: z23.string().nullable(),
3161
+ archivedAt: z23.string().nullable(),
3162
+ config: z23.record(z23.string(), z23.unknown()),
3163
+ createdAt: z23.string(),
3164
+ updatedAt: z23.string()
3165
+ });
3166
+ var trafficConnectCloudRunRequestSchema = z23.object({
3167
+ gcpProjectId: z23.string().min(1),
3168
+ serviceName: z23.string().min(1).optional(),
3169
+ location: z23.string().min(1).optional(),
3170
+ displayName: z23.string().min(1).optional(),
2355
3171
  /** Service-account JSON content (string). When omitted, defaults to OAuth via `canonry google connect <project> --type ga4` flow. */
2356
- keyJson: z20.string().optional()
3172
+ keyJson: z23.string().optional()
2357
3173
  });
2358
- var trafficConnectWordpressRequestSchema = z20.object({
2359
- baseUrl: z20.string().url(),
2360
- username: z20.string().min(1),
3174
+ var trafficConnectWordpressRequestSchema = z23.object({
3175
+ baseUrl: z23.string().url(),
3176
+ username: z23.string().min(1),
2361
3177
  /** WordPress Application Password (the same auth used by the content client). */
2362
- applicationPassword: z20.string().min(1),
2363
- displayName: z20.string().min(1).optional()
3178
+ applicationPassword: z23.string().min(1),
3179
+ displayName: z23.string().min(1).optional()
2364
3180
  });
2365
- var trafficConnectVercelRequestSchema = z20.object({
3181
+ var trafficConnectVercelRequestSchema = z23.object({
2366
3182
  /** Vercel project id (e.g. `prj_...`) — from the Vercel dashboard or `.vercel/project.json`. */
2367
- projectId: z20.string().min(1),
3183
+ projectId: z23.string().min(1),
2368
3184
  /** Vercel team / owner id (e.g. `team_...`). */
2369
- teamId: z20.string().min(1),
3185
+ teamId: z23.string().min(1),
2370
3186
  /** Vercel API token (personal access token). Stored in `~/.canonry/config.yaml`, never the DB. */
2371
- token: z20.string().min(1),
3187
+ token: z23.string().min(1),
2372
3188
  /** Which deployment environment's request logs to pull. Default: `production`. */
2373
3189
  environment: vercelTrafficEnvironmentSchema.optional(),
2374
- displayName: z20.string().min(1).optional()
2375
- });
2376
- var trafficSyncResponseSchema = z20.object({
2377
- sourceId: z20.string(),
2378
- runId: z20.string(),
2379
- syncedAt: z20.string(),
2380
- pulledEvents: z20.number().int().nonnegative(),
2381
- crawlerHits: z20.number().int().nonnegative(),
2382
- aiReferralHits: z20.number().int().nonnegative(),
2383
- unknownHits: z20.number().int().nonnegative(),
2384
- crawlerBucketRows: z20.number().int().nonnegative(),
2385
- aiReferralBucketRows: z20.number().int().nonnegative(),
2386
- sampleRows: z20.number().int().nonnegative(),
2387
- windowStart: z20.string(),
2388
- windowEnd: z20.string()
2389
- });
2390
- var trafficBackfillRequestSchema = z20.object({
3190
+ displayName: z23.string().min(1).optional()
3191
+ });
3192
+ var trafficSyncResponseSchema = z23.object({
3193
+ sourceId: z23.string(),
3194
+ runId: z23.string(),
3195
+ syncedAt: z23.string(),
3196
+ pulledEvents: z23.number().int().nonnegative(),
3197
+ crawlerHits: z23.number().int().nonnegative(),
3198
+ aiReferralHits: z23.number().int().nonnegative(),
3199
+ unknownHits: z23.number().int().nonnegative(),
3200
+ crawlerBucketRows: z23.number().int().nonnegative(),
3201
+ aiReferralBucketRows: z23.number().int().nonnegative(),
3202
+ sampleRows: z23.number().int().nonnegative(),
3203
+ windowStart: z23.string(),
3204
+ windowEnd: z23.string()
3205
+ });
3206
+ var trafficBackfillRequestSchema = z23.object({
2391
3207
  /** Lookback window in days. Capped server-side at the upstream log retention ceiling (Cloud Logging _Default = 30d). Default: 30. */
2392
- days: z20.number().int().positive().optional()
3208
+ days: z23.number().int().positive().optional()
2393
3209
  });
2394
- var trafficBackfillResponseSchema = z20.object({
2395
- sourceId: z20.string(),
2396
- runId: z20.string(),
3210
+ var trafficBackfillResponseSchema = z23.object({
3211
+ sourceId: z23.string(),
3212
+ runId: z23.string(),
2397
3213
  status: runStatusSchema,
2398
- windowStart: z20.string(),
2399
- windowEnd: z20.string(),
3214
+ windowStart: z23.string(),
3215
+ windowEnd: z23.string(),
2400
3216
  /** Days actually used after server-side clamping (≤ requested). */
2401
- daysRequested: z20.number().int().positive(),
2402
- daysApplied: z20.number().int().positive()
3217
+ daysRequested: z23.number().int().positive(),
3218
+ daysApplied: z23.number().int().positive()
2403
3219
  });
2404
- var trafficSourceTotalsSchema = z20.object({
2405
- crawlerHits: z20.number().int().nonnegative(),
2406
- aiReferralHits: z20.number().int().nonnegative(),
2407
- sampleCount: z20.number().int().nonnegative()
3220
+ var trafficSourceTotalsSchema = z23.object({
3221
+ crawlerHits: z23.number().int().nonnegative(),
3222
+ aiReferralHits: z23.number().int().nonnegative(),
3223
+ sampleCount: z23.number().int().nonnegative()
2408
3224
  });
2409
- var trafficSourceListResponseSchema = z20.object({
2410
- sources: z20.array(trafficSourceDtoSchema)
3225
+ var trafficSourceListResponseSchema = z23.object({
3226
+ sources: z23.array(trafficSourceDtoSchema)
2411
3227
  });
2412
3228
  var trafficSourceDetailDtoSchema = trafficSourceDtoSchema.extend({
2413
3229
  totals24h: trafficSourceTotalsSchema,
2414
- latestRun: z20.object({
2415
- runId: z20.string(),
3230
+ latestRun: z23.object({
3231
+ runId: z23.string(),
2416
3232
  status: runStatusSchema,
2417
- startedAt: z20.string().nullable(),
2418
- finishedAt: z20.string().nullable(),
2419
- error: z20.string().nullable()
3233
+ startedAt: z23.string().nullable(),
3234
+ finishedAt: z23.string().nullable(),
3235
+ error: z23.string().nullable()
2420
3236
  }).nullable()
2421
3237
  });
2422
- var trafficStatusResponseSchema = z20.object({
2423
- sources: z20.array(trafficSourceDetailDtoSchema)
3238
+ var trafficStatusResponseSchema = z23.object({
3239
+ sources: z23.array(trafficSourceDetailDtoSchema)
2424
3240
  });
2425
- var trafficEventKindSchema = z20.enum(["crawler", "ai-referral"]);
3241
+ var trafficEventKindSchema = z23.enum(["crawler", "ai-referral"]);
2426
3242
  var TrafficEventKinds = trafficEventKindSchema.enum;
2427
- var trafficCrawlerEventEntrySchema = z20.object({
2428
- kind: z20.literal(TrafficEventKinds.crawler),
2429
- sourceId: z20.string(),
2430
- tsHour: z20.string(),
2431
- botId: z20.string(),
2432
- operator: z20.string(),
2433
- verificationStatus: z20.string(),
2434
- pathNormalized: z20.string(),
2435
- status: z20.number().int(),
2436
- hits: z20.number().int().nonnegative()
2437
- });
2438
- var trafficAiReferralEventEntrySchema = z20.object({
2439
- kind: z20.literal(TrafficEventKinds["ai-referral"]),
2440
- sourceId: z20.string(),
2441
- tsHour: z20.string(),
2442
- product: z20.string(),
2443
- operator: z20.string(),
2444
- sourceDomain: z20.string(),
2445
- evidenceType: z20.string(),
2446
- landingPathNormalized: z20.string(),
2447
- status: z20.number().int(),
2448
- hits: z20.number().int().nonnegative()
2449
- });
2450
- var trafficEventEntrySchema = z20.discriminatedUnion("kind", [
3243
+ var trafficCrawlerEventEntrySchema = z23.object({
3244
+ kind: z23.literal(TrafficEventKinds.crawler),
3245
+ sourceId: z23.string(),
3246
+ tsHour: z23.string(),
3247
+ botId: z23.string(),
3248
+ operator: z23.string(),
3249
+ verificationStatus: z23.string(),
3250
+ pathNormalized: z23.string(),
3251
+ status: z23.number().int(),
3252
+ hits: z23.number().int().nonnegative()
3253
+ });
3254
+ var trafficAiReferralEventEntrySchema = z23.object({
3255
+ kind: z23.literal(TrafficEventKinds["ai-referral"]),
3256
+ sourceId: z23.string(),
3257
+ tsHour: z23.string(),
3258
+ product: z23.string(),
3259
+ operator: z23.string(),
3260
+ sourceDomain: z23.string(),
3261
+ evidenceType: z23.string(),
3262
+ landingPathNormalized: z23.string(),
3263
+ status: z23.number().int(),
3264
+ hits: z23.number().int().nonnegative()
3265
+ });
3266
+ var trafficEventEntrySchema = z23.discriminatedUnion("kind", [
2451
3267
  trafficCrawlerEventEntrySchema,
2452
3268
  trafficAiReferralEventEntrySchema
2453
3269
  ]);
2454
- var trafficEventsResponseSchema = z20.object({
2455
- windowStart: z20.string(),
2456
- windowEnd: z20.string(),
2457
- totals: z20.object({
2458
- crawlerHits: z20.number().int().nonnegative(),
2459
- aiReferralHits: z20.number().int().nonnegative()
3270
+ var trafficEventsResponseSchema = z23.object({
3271
+ windowStart: z23.string(),
3272
+ windowEnd: z23.string(),
3273
+ totals: z23.object({
3274
+ crawlerHits: z23.number().int().nonnegative(),
3275
+ aiReferralHits: z23.number().int().nonnegative()
2460
3276
  }),
2461
- events: z20.array(trafficEventEntrySchema)
3277
+ events: z23.array(trafficEventEntrySchema)
2462
3278
  });
2463
3279
 
2464
3280
  // ../contracts/src/discovery.ts
2465
- import { z as z21 } from "zod";
2466
- var discoveryBucketSchema = z21.enum(["cited", "aspirational", "wasted-surface"]);
3281
+ import { z as z24 } from "zod";
3282
+ var discoveryBucketSchema = z24.enum(["cited", "aspirational", "wasted-surface"]);
2467
3283
  var DiscoveryBuckets = discoveryBucketSchema.enum;
2468
3284
  var DEFAULT_DISCOVERY_PROMOTE_BUCKETS = [
2469
3285
  DiscoveryBuckets.cited,
@@ -2471,7 +3287,7 @@ var DEFAULT_DISCOVERY_PROMOTE_BUCKETS = [
2471
3287
  ];
2472
3288
  var DISCOVERY_PROMOTE_COMPETITOR_CAP = 20;
2473
3289
  var DISCOVERY_PROMOTE_COMPETITOR_MIN_HITS = 2;
2474
- var discoveryCompetitorTypeSchema = z21.enum([
3290
+ var discoveryCompetitorTypeSchema = z24.enum([
2475
3291
  "direct-competitor",
2476
3292
  "ota-aggregator",
2477
3293
  "editorial-media",
@@ -2482,11 +3298,11 @@ var DiscoveryCompetitorTypes = discoveryCompetitorTypeSchema.enum;
2482
3298
  var DEFAULT_DISCOVERY_PROMOTE_COMPETITOR_TYPES = [
2483
3299
  DiscoveryCompetitorTypes["direct-competitor"]
2484
3300
  ];
2485
- var discoverySessionStatusSchema = z21.enum(["queued", "seeding", "probing", "completed", "failed"]);
3301
+ var discoverySessionStatusSchema = z24.enum(["queued", "seeding", "probing", "completed", "failed"]);
2486
3302
  var DiscoverySessionStatuses = discoverySessionStatusSchema.enum;
2487
- var discoveryCompetitorMapEntrySchema = z21.object({
2488
- domain: z21.string().min(1),
2489
- hits: z21.number().int().positive(),
3303
+ var discoveryCompetitorMapEntrySchema = z24.object({
3304
+ domain: z24.string().min(1),
3305
+ hits: z24.number().int().positive(),
2490
3306
  /**
2491
3307
  * Domain classification from the session's post-probe AI classification
2492
3308
  * pass. Defaults to `unknown` so competitor maps persisted before
@@ -2495,43 +3311,43 @@ var discoveryCompetitorMapEntrySchema = z21.object({
2495
3311
  */
2496
3312
  competitorType: discoveryCompetitorTypeSchema.default("unknown")
2497
3313
  });
2498
- var discoveryProbeDtoSchema = z21.object({
2499
- id: z21.string(),
2500
- sessionId: z21.string(),
2501
- projectId: z21.string(),
2502
- query: z21.string(),
3314
+ var discoveryProbeDtoSchema = z24.object({
3315
+ id: z24.string(),
3316
+ sessionId: z24.string(),
3317
+ projectId: z24.string(),
3318
+ query: z24.string(),
2503
3319
  bucket: discoveryBucketSchema.nullable().default(null),
2504
3320
  citationState: citationStateSchema,
2505
- citedDomains: z21.array(z21.string()).default([]),
2506
- createdAt: z21.string()
3321
+ citedDomains: z24.array(z24.string()).default([]),
3322
+ createdAt: z24.string()
2507
3323
  });
2508
- var discoverySessionDtoSchema = z21.object({
2509
- id: z21.string(),
2510
- projectId: z21.string(),
3324
+ var discoverySessionDtoSchema = z24.object({
3325
+ id: z24.string(),
3326
+ projectId: z24.string(),
2511
3327
  status: discoverySessionStatusSchema,
2512
- icpDescription: z21.string().nullable().optional(),
2513
- seedProvider: z21.string().nullable().optional(),
2514
- seedCountRaw: z21.number().int().nullable().optional(),
2515
- seedCount: z21.number().int().nullable().optional(),
2516
- dedupThreshold: z21.number().nullable().optional(),
2517
- probeCount: z21.number().int().nullable().optional(),
2518
- citedCount: z21.number().int().nullable().default(null),
2519
- aspirationalCount: z21.number().int().nullable().default(null),
2520
- wastedCount: z21.number().int().nullable().default(null),
2521
- competitorMap: z21.array(discoveryCompetitorMapEntrySchema).default([]),
2522
- error: z21.string().nullable().optional(),
2523
- startedAt: z21.string().nullable().optional(),
2524
- finishedAt: z21.string().nullable().optional(),
2525
- createdAt: z21.string()
3328
+ icpDescription: z24.string().nullable().optional(),
3329
+ seedProvider: z24.string().nullable().optional(),
3330
+ seedCountRaw: z24.number().int().nullable().optional(),
3331
+ seedCount: z24.number().int().nullable().optional(),
3332
+ dedupThreshold: z24.number().nullable().optional(),
3333
+ probeCount: z24.number().int().nullable().optional(),
3334
+ citedCount: z24.number().int().nullable().default(null),
3335
+ aspirationalCount: z24.number().int().nullable().default(null),
3336
+ wastedCount: z24.number().int().nullable().default(null),
3337
+ competitorMap: z24.array(discoveryCompetitorMapEntrySchema).default([]),
3338
+ error: z24.string().nullable().optional(),
3339
+ startedAt: z24.string().nullable().optional(),
3340
+ finishedAt: z24.string().nullable().optional(),
3341
+ createdAt: z24.string()
2526
3342
  });
2527
3343
  var discoverySessionDetailDtoSchema = discoverySessionDtoSchema.extend({
2528
- probes: z21.array(discoveryProbeDtoSchema).default([])
3344
+ probes: z24.array(discoveryProbeDtoSchema).default([])
2529
3345
  });
2530
3346
  var DISCOVERY_MAX_PROBES_CAP = 500;
2531
- var discoveryRunRequestSchema = z21.object({
2532
- icpDescription: z21.string().min(1).optional(),
2533
- dedupThreshold: z21.number().min(0).max(1).optional(),
2534
- maxProbes: z21.number().int().positive().max(DISCOVERY_MAX_PROBES_CAP).optional(),
3347
+ var discoveryRunRequestSchema = z24.object({
3348
+ icpDescription: z24.string().min(1).optional(),
3349
+ dedupThreshold: z24.number().min(0).max(1).optional(),
3350
+ maxProbes: z24.number().int().positive().max(DISCOVERY_MAX_PROBES_CAP).optional(),
2535
3351
  /**
2536
3352
  * Optional override of the project's location labels, constraining seed
2537
3353
  * generation to a subset of the configured service areas. Each label must
@@ -2539,39 +3355,39 @@ var discoveryRunRequestSchema = z21.object({
2539
3355
  * `resolveLocations`). Omitted means "use every project location" — a
2540
3356
  * project with no locations is unaffected.
2541
3357
  */
2542
- locations: z21.array(z21.string().min(1)).optional()
3358
+ locations: z24.array(z24.string().min(1)).optional()
2543
3359
  });
2544
- var discoveryPromoteRequestSchema = z21.object({
2545
- buckets: z21.array(discoveryBucketSchema).min(1).optional(),
2546
- includeCompetitors: z21.boolean().optional(),
2547
- competitorTypes: z21.array(discoveryCompetitorTypeSchema).min(1).optional()
3360
+ var discoveryPromoteRequestSchema = z24.object({
3361
+ buckets: z24.array(discoveryBucketSchema).min(1).optional(),
3362
+ includeCompetitors: z24.boolean().optional(),
3363
+ competitorTypes: z24.array(discoveryCompetitorTypeSchema).min(1).optional()
2548
3364
  });
2549
- var discoveryPromotePreviewSchema = z21.object({
2550
- sessionId: z21.string(),
2551
- projectId: z21.string(),
3365
+ var discoveryPromotePreviewSchema = z24.object({
3366
+ sessionId: z24.string(),
3367
+ projectId: z24.string(),
2552
3368
  status: discoverySessionStatusSchema,
2553
- queriesByBucket: z21.object({
2554
- cited: z21.array(z21.string()),
2555
- aspirational: z21.array(z21.string()),
2556
- "wasted-surface": z21.array(z21.string())
3369
+ queriesByBucket: z24.object({
3370
+ cited: z24.array(z24.string()),
3371
+ aspirational: z24.array(z24.string()),
3372
+ "wasted-surface": z24.array(z24.string())
2557
3373
  }),
2558
- suggestedCompetitors: z21.array(discoveryCompetitorMapEntrySchema)
2559
- });
2560
- var discoveryPromoteResultSchema = z21.object({
2561
- sessionId: z21.string(),
2562
- projectId: z21.string(),
2563
- promoted: z21.object({
2564
- queries: z21.array(z21.string()),
2565
- competitors: z21.array(z21.string())
3374
+ suggestedCompetitors: z24.array(discoveryCompetitorMapEntrySchema)
3375
+ });
3376
+ var discoveryPromoteResultSchema = z24.object({
3377
+ sessionId: z24.string(),
3378
+ projectId: z24.string(),
3379
+ promoted: z24.object({
3380
+ queries: z24.array(z24.string()),
3381
+ competitors: z24.array(z24.string())
2566
3382
  }),
2567
- skipped: z21.object({
2568
- queries: z21.array(z21.string()),
2569
- competitors: z21.array(z21.string())
3383
+ skipped: z24.object({
3384
+ queries: z24.array(z24.string()),
3385
+ competitors: z24.array(z24.string())
2570
3386
  })
2571
3387
  });
2572
- var queryProvenanceSchema = z21.union([
2573
- z21.literal("cli"),
2574
- z21.string().regex(/^discovery:.+$/)
3388
+ var queryProvenanceSchema = z24.union([
3389
+ z24.literal("cli"),
3390
+ z24.string().regex(/^discovery:.+$/)
2575
3391
  ]);
2576
3392
 
2577
3393
  // ../contracts/src/embeddings.ts
@@ -2752,6 +3568,7 @@ export {
2752
3568
  locationContextSchema,
2753
3569
  getProviderLocationHandling,
2754
3570
  notificationEventSchema,
3571
+ notificationDtoSchema,
2755
3572
  notificationCreateRequestSchema,
2756
3573
  AppError,
2757
3574
  notFound,
@@ -2771,10 +3588,14 @@ export {
2771
3588
  hasLocationLabel,
2772
3589
  resolveLocations,
2773
3590
  projectUpsertRequestSchema,
3591
+ projectDtoSchema,
3592
+ queryDtoSchema,
3593
+ keywordDtoSchema,
2774
3594
  queryBatchRequestSchema,
2775
3595
  keywordBatchRequestSchema,
2776
3596
  queryGenerateRequestSchema,
2777
3597
  keywordGenerateRequestSchema,
3598
+ competitorDtoSchema,
2778
3599
  competitorBatchRequestSchema,
2779
3600
  normalizeProjectDomain,
2780
3601
  registrableDomain,
@@ -2784,50 +3605,116 @@ export {
2784
3605
  effectiveBrandNames,
2785
3606
  projectConfigSchema,
2786
3607
  resolveConfigSpecQueries,
3608
+ googleConnectionDtoSchema,
3609
+ gscSearchDataDtoSchema,
3610
+ gscPerformanceDailyDtoSchema,
3611
+ gscUrlInspectionDtoSchema,
3612
+ gscDeindexedRowSchema,
3613
+ gscCoverageSummaryDtoSchema,
3614
+ indexingRequestResponseDtoSchema,
3615
+ gscCoverageSnapshotDtoSchema,
3616
+ gscSiteListResponseDtoSchema,
3617
+ gscSitemapListResponseDtoSchema,
3618
+ bingUrlInspectionDtoSchema,
3619
+ bingCoverageSummaryDtoSchema,
3620
+ bingKeywordStatsDtoSchema,
3621
+ bingCoverageSnapshotDtoSchema,
3622
+ bingIndexingRequestResponseDtoSchema,
3623
+ bingSitesResponseDtoSchema,
3624
+ bingStatusDtoSchema,
3625
+ bingConnectResponseDtoSchema,
3626
+ bingSetSiteResponseDtoSchema,
3627
+ cdpStatusDtoSchema,
2787
3628
  wordpressEnvSchema,
3629
+ wordpressStatusDtoSchema,
3630
+ wordpressPageSummaryDtoSchema,
3631
+ wordpressSchemaBlockDtoSchema,
3632
+ wordpressPageDetailDtoSchema,
3633
+ wordpressManualAssistDtoSchema,
3634
+ wordpressAuditPageDtoSchema,
3635
+ wordpressBulkMetaResultDtoSchema,
3636
+ wordpressSchemaDeployResultDtoSchema,
3637
+ wordpressSchemaStatusResultDtoSchema,
3638
+ wordpressOnboardResultDtoSchema,
3639
+ wordpressDiffDtoSchema,
2788
3640
  AgentProviderIds,
2789
3641
  AGENT_PROVIDER_IDS,
2790
3642
  isAgentProviderId,
3643
+ LlmCapabilities,
3644
+ LLM_CAPABILITIES,
3645
+ settingsDtoSchema,
2791
3646
  RunStatuses,
2792
3647
  RunKinds,
2793
3648
  RunTriggers,
2794
3649
  citationStateSchema,
2795
3650
  CitationStates,
2796
3651
  runTriggerRequestSchema,
3652
+ runDtoSchema,
2797
3653
  parseRunError,
2798
3654
  buildRunErrorFromMessages,
2799
3655
  serializeRunError,
2800
3656
  formatRunErrorOneLine,
3657
+ snapshotListResponseSchema,
3658
+ snapshotDiffResponseSchema,
3659
+ runDetailDtoSchema,
3660
+ latestProjectRunDtoSchema,
3661
+ auditLogEntrySchema,
2801
3662
  snapshotRequestSchema,
2802
3663
  resolveSnapshotRequestQueries,
3664
+ snapshotReportSchema,
2803
3665
  schedulableRunKindSchema,
2804
3666
  SchedulableRunKinds,
3667
+ scheduleDtoSchema,
2805
3668
  scheduleUpsertRequestSchema,
2806
3669
  parseWindow,
2807
3670
  windowCutoff,
2808
3671
  categorizeSource,
2809
3672
  categorizeSourceWithCompetitors,
2810
3673
  categoryLabel,
3674
+ ga4StatusDtoSchema,
3675
+ ga4SyncResponseDtoSchema,
3676
+ ga4AiReferralHistoryEntrySchema,
3677
+ ga4SocialReferralHistoryEntrySchema,
3678
+ ga4SessionHistoryEntrySchema,
2811
3679
  extractAnswerMentions,
2812
3680
  determineAnswerMentioned,
2813
3681
  visibilityStateFromAnswerMentioned,
2814
3682
  mentionStateFromAnswerMentioned,
2815
3683
  brandKeyFromText,
3684
+ agentProvidersResponseDtoSchema,
2816
3685
  MemorySources,
2817
3686
  AGENT_MEMORY_VALUE_MAX_BYTES,
2818
3687
  AGENT_MEMORY_KEY_MAX_LENGTH,
2819
3688
  agentMemoryUpsertRequestSchema,
2820
3689
  agentMemoryDeleteRequestSchema,
2821
3690
  CcReleaseSyncStatuses,
3691
+ ccReleaseSyncDtoSchema,
3692
+ backlinkSummaryDtoSchema,
3693
+ backlinkListResponseSchema,
3694
+ backlinkHistoryEntrySchema,
3695
+ backlinksInstallStatusDtoSchema,
3696
+ backlinksInstallResultDtoSchema,
3697
+ ccAvailableReleaseSchema,
3698
+ ccCachedReleaseSchema,
2822
3699
  ContentActions,
2823
3700
  contentActionLabel,
2824
3701
  actionConfidenceLabel,
3702
+ contentTargetsResponseDtoSchema,
3703
+ contentTargetDismissalDtoSchema,
3704
+ contentTargetDismissalsResponseDtoSchema,
3705
+ contentTargetDismissRequestSchema,
3706
+ recommendationExplanationDtoSchema,
3707
+ recommendationExplainRequestSchema,
3708
+ contentSourcesResponseDtoSchema,
3709
+ contentGapsResponseDtoSchema,
2825
3710
  CheckStatuses,
2826
3711
  CheckScopes,
2827
3712
  CheckCategories,
3713
+ doctorReportSchema,
2828
3714
  summarizeCheckResults,
2829
3715
  absolutizeProjectUrl,
2830
3716
  normalizeUrlPath,
3717
+ citationVisibilityResponseSchema,
2831
3718
  emptyCitationVisibility,
2832
3719
  citationStateToCited,
2833
3720
  reportActionTone,
@@ -2835,6 +3722,7 @@ export {
2835
3722
  reportHorizonLabel,
2836
3723
  reportActionCategoryLabel,
2837
3724
  reportConfidenceLabel,
3725
+ projectReportDtoSchema,
2838
3726
  dedupeReportActions,
2839
3727
  dedupeReportOpportunities,
2840
3728
  CodingAgents,
@@ -2846,11 +3734,18 @@ export {
2846
3734
  TrafficSourceStatuses,
2847
3735
  TrafficSourceAuthModes,
2848
3736
  VerificationStatuses,
3737
+ trafficSourceDtoSchema,
2849
3738
  trafficConnectCloudRunRequestSchema,
2850
3739
  trafficConnectWordpressRequestSchema,
2851
3740
  trafficConnectVercelRequestSchema,
3741
+ trafficSyncResponseSchema,
3742
+ trafficBackfillResponseSchema,
3743
+ trafficSourceListResponseSchema,
3744
+ trafficSourceDetailDtoSchema,
3745
+ trafficStatusResponseSchema,
2852
3746
  trafficEventKindSchema,
2853
3747
  TrafficEventKinds,
3748
+ trafficEventsResponseSchema,
2854
3749
  discoveryBucketSchema,
2855
3750
  DiscoveryBuckets,
2856
3751
  DEFAULT_DISCOVERY_PROMOTE_BUCKETS,
@@ -2860,9 +3755,13 @@ export {
2860
3755
  DiscoveryCompetitorTypes,
2861
3756
  DEFAULT_DISCOVERY_PROMOTE_COMPETITOR_TYPES,
2862
3757
  DiscoverySessionStatuses,
3758
+ discoverySessionDtoSchema,
3759
+ discoverySessionDetailDtoSchema,
2863
3760
  DISCOVERY_MAX_PROBES_CAP,
2864
3761
  discoveryRunRequestSchema,
2865
3762
  discoveryPromoteRequestSchema,
3763
+ discoveryPromotePreviewSchema,
3764
+ discoveryPromoteResultSchema,
2866
3765
  clusterByCosine,
2867
3766
  pickClusterRepresentative,
2868
3767
  formatRatio,