@canonry/canonry 5.19.0 → 5.20.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 (32) hide show
  1. package/assets/agent-workspace/skills/aero/SKILL.md +13 -8
  2. package/assets/agent-workspace/skills/aero/references/portfolio-analysis.md +27 -10
  3. package/assets/agent-workspace/skills/canonry/references/canonry-cli.md +7 -2
  4. package/assets/assets/{AuditHistoryPanel-C_p8jX7Q.js → AuditHistoryPanel-BSh3Oezj.js} +1 -1
  5. package/assets/assets/{BacklinksPage-jD4nOGw1.js → BacklinksPage-DQ59dhCx.js} +1 -1
  6. package/assets/assets/{HistoryPage-DJGBbtBY.js → HistoryPage-BBvgid3o.js} +1 -1
  7. package/assets/assets/{MeasurementPropertyPage-Dmr3TVlo.js → MeasurementPropertyPage-Dmb18JbT.js} +1 -1
  8. package/assets/assets/{ProjectPage-B_haCKiA.js → ProjectPage-CPg0q2Dy.js} +1 -1
  9. package/assets/assets/{RunRow-BMbwR2yk.js → RunRow-BK8sZCID.js} +1 -1
  10. package/assets/assets/{RunsPage-D8hHakq2.js → RunsPage-CIcVBTdP.js} +1 -1
  11. package/assets/assets/{SettingsPage-QKnRcFA9.js → SettingsPage-Bc3aR-gz.js} +1 -1
  12. package/assets/assets/{SiteHealthSection-CDkUXqmb.js → SiteHealthSection-FF14aIXT.js} +3 -3
  13. package/assets/assets/{TrafficPage-CMif8RlM.js → TrafficPage-C_qoeGDl.js} +1 -1
  14. package/assets/assets/{TrafficSourceDetailPage-DOCTP_4-.js → TrafficSourceDetailPage-B3i_B2MI.js} +1 -1
  15. package/assets/assets/{extract-error-message-Dm8RvYE5.js → extract-error-message-BisUn6nN.js} +1 -1
  16. package/assets/assets/{index-lj0fuFl4.js → index-Dht7JNX5.js} +44 -44
  17. package/assets/assets/{react-sigma_core.esm.min-DOPuwLtN.js → react-sigma_core.esm.min-tWhS09SS.js} +1 -1
  18. package/assets/assets/{v2-overview-adapter-C19tUcDS.js → v2-overview-adapter-CAoeWKQJ.js} +1 -1
  19. package/assets/index.html +1 -1
  20. package/dist/{chunk-QJWIOCEO.js → chunk-4PENJKRN.js} +2 -2
  21. package/dist/{chunk-SPCEXW3B.js → chunk-5FKR2K76.js} +11 -4
  22. package/dist/{chunk-GUJY3RIM.js → chunk-DRZWMFRV.js} +627 -263
  23. package/dist/{chunk-WLL7Q7JD.js → chunk-QF7SY7AF.js} +222 -29
  24. package/dist/{chunk-ABUO27BV.js → chunk-TSFKNQ5X.js} +3 -3
  25. package/dist/{chunk-P2EFPLIO.js → chunk-WL27HO5C.js} +565 -139
  26. package/dist/{chunk-YHKKCXGY.js → chunk-XBGPHZKA.js} +24 -8
  27. package/dist/cli.js +73 -17
  28. package/dist/{demo-server-BOIBS74F.js → demo-server-OCBV5OMS.js} +4 -4
  29. package/dist/index.js +6 -6
  30. package/dist/{intelligence-service-IWR2H6OW.js → intelligence-service-MKHINDHN.js} +2 -2
  31. package/dist/mcp.js +4 -4
  32. package/package.json +14 -14
@@ -248,11 +248,6 @@ var PROVIDER_LOCATION_HANDLING = {
248
248
  supportsLocationContext: true,
249
249
  description: "Location appended to the query text the Gemini model receives."
250
250
  },
251
- perplexity: {
252
- treatment: "prompt",
253
- supportsLocationContext: true,
254
- description: "Location appended to the query text the Perplexity model receives."
255
- },
256
251
  local: {
257
252
  treatment: "prompt",
258
253
  supportsLocationContext: true,
@@ -268,6 +263,11 @@ var PROVIDER_LOCATION_HANDLING = {
268
263
  supportsLocationContext: true,
269
264
  description: "Location sent as a structured `user_location` field on Anthropic\u2019s web_search_20250305 tool."
270
265
  },
266
+ perplexity: {
267
+ treatment: "request-param",
268
+ supportsLocationContext: true,
269
+ description: "Location sent as a structured `user_location` field on Perplexity\u2019s web_search tool."
270
+ },
271
271
  "cdp:chatgpt": {
272
272
  treatment: "browser-geo",
273
273
  supportsLocationContext: false,
@@ -4383,6 +4383,25 @@ var measurementPropertyEvidenceQuerySchema = z6.object({
4383
4383
  limit: z6.number().int().positive().max(MEASUREMENT_PAGE_MAX_LIMIT).optional()
4384
4384
  }).strict();
4385
4385
 
4386
+ // ../contracts/src/models.ts
4387
+ var PROVIDER_MODEL_ALIASES = {
4388
+ perplexity: {
4389
+ sonar: "fast",
4390
+ "sonar-pro": "low",
4391
+ "sonar-reasoning": "low",
4392
+ "sonar-reasoning-pro": "low",
4393
+ "sonar-deep-research": "medium",
4394
+ "fast-search": "fast",
4395
+ "pro-search": "low",
4396
+ "deep-research": "medium",
4397
+ "advanced-deep-research": "high"
4398
+ }
4399
+ };
4400
+ function resolveProviderModel(provider, model) {
4401
+ const aliases = PROVIDER_MODEL_ALIASES[provider];
4402
+ return aliases !== void 0 && Object.hasOwn(aliases, model) ? aliases[model] : model;
4403
+ }
4404
+
4386
4405
  // ../contracts/src/measurement-plan.ts
4387
4406
  var MEASUREMENT_PLAN_SCHEMA_VERSION = 1;
4388
4407
  var measurementPlanRevisionSchema = z7.number().int().positive();
@@ -4762,7 +4781,7 @@ function normalizeExecutionIdentity(input) {
4762
4781
  const models = {};
4763
4782
  for (const provider of providers) {
4764
4783
  const model = input.models[provider];
4765
- if (model && model.trim()) models[provider] = model.trim();
4784
+ if (model && model.trim()) models[provider] = resolveProviderModel(provider, model.trim());
4766
4785
  }
4767
4786
  return { providers, models };
4768
4787
  }
@@ -7157,25 +7176,97 @@ var measurementDemoFilterQueryShape = {
7157
7176
  location: measurementDemoLocationSchema.optional()
7158
7177
  };
7159
7178
  var measurementDemoRecommendedNameSchema = z18.string().trim().min(1);
7179
+ var MEASUREMENT_PORTFOLIO_DEFAULT_LIMIT = 4;
7180
+ var MEASUREMENT_PORTFOLIO_ROW_EVIDENCE_LIMIT = 5;
7181
+ var MEASUREMENT_PORTFOLIO_ANSWER_SOURCES_LIMIT = 10;
7182
+ var MEASUREMENT_PORTFOLIO_TIE_NOTE = "tied Properties are ordered by name, not ranked";
7160
7183
  var measurementPortfolioSummaryQuerySchema = z18.object({
7161
7184
  runId: measurementDemoFilterQueryShape.runId,
7162
7185
  groupKey: measurementV2StableKeySchema.optional(),
7163
7186
  queryClass: measurementQueryClassFilterSchema.default("non-brand"),
7164
7187
  provider: measurementDemoFilterQueryShape.provider,
7165
7188
  location: measurementDemoFilterQueryShape.location,
7166
- limit: z18.number().int().positive().max(50).optional()
7189
+ /** Caps every list in the response (Property rows, both mention rankings, markets). Defaults to 4. */
7190
+ limit: z18.number().int().positive().max(50).optional(),
7191
+ /**
7192
+ * Off by default: `markets` holds one level only, the top-level markets (or
7193
+ * the selected group's direct children), worst-first and capped at `limit`.
7194
+ * True returns every market in scope at every level, uncapped, as the
7195
+ * roll-up did before it was levelled.
7196
+ */
7197
+ includeNestedMarkets: z18.boolean().optional()
7198
+ }).strict();
7199
+ var measurementPortfolioMetroSchema = z18.object({
7200
+ groupKey: measurementV2StableKeySchema,
7201
+ label: measurementDemoLabelSchema
7202
+ }).strict();
7203
+ var measurementPortfolioPropertyContextShape = {
7204
+ /** The top-level group holding this Property; null when it is in none. */
7205
+ metro: measurementPortfolioMetroSchema.nullable(),
7206
+ /** Further top-level groups holding the same Property. Present only when there are any. */
7207
+ otherMetros: z18.array(measurementPortfolioMetroSchema).min(1).optional(),
7208
+ /** Labels of every nested (non-top-level) group holding this Property, shallowest first. */
7209
+ submarkets: z18.array(measurementDemoLabelSchema),
7210
+ queries: measurementDemoCountSchema
7211
+ };
7212
+ var measurementPortfolioCountedNameSchema = z18.object({
7213
+ name: measurementDemoRecommendedNameSchema,
7214
+ /** Answers that wrote this name. */
7215
+ answers: measurementDemoCountSchema
7216
+ }).strict();
7217
+ var measurementPortfolioRecommendedInsteadSchema = z18.object({
7218
+ name: measurementDemoRecommendedNameSchema,
7219
+ /** Answers that wrote this name, one per answer however it spells it: the same count as `namedInsteadInAnswerText[].answers`. */
7220
+ occurrences: measurementDemoCountSchema
7221
+ }).strict();
7222
+ var measurementPortfolioCountedDomainSchema = z18.object({
7223
+ domain: z18.string().trim().min(1),
7224
+ /** Answers citing at least one URL on this domain. */
7225
+ answers: measurementDemoCountSchema
7167
7226
  }).strict();
7168
7227
  var measurementPortfolioWeakestPropertySchema = measurementDemoPropertySchema.extend({
7228
+ ...measurementPortfolioPropertyContextShape,
7169
7229
  mentionCoverage: measurementMetricValueSchema,
7170
7230
  citationCoverage: measurementMetricValueSchema,
7171
7231
  flags: measurementDemoCountSchema,
7172
- recommendedInstead: z18.array(z18.object({
7173
- name: measurementDemoRecommendedNameSchema,
7174
- occurrences: measurementDemoCountSchema
7175
- }).strict()).max(5),
7176
- recommendedInsteadTotal: measurementDemoCountSchema,
7177
- recommendedInsteadTruncated: z18.boolean()
7232
+ /**
7233
+ * Names WRITTEN IN THE ANSWER TEXT of this Property's answers that neither
7234
+ * named nor cited it, counted by answer. These are mentions, never
7235
+ * citations: a name here says nothing about which sources were linked.
7236
+ * Supersedes the deprecated `recommendedInstead`, whose name read as a
7237
+ * citation.
7238
+ */
7239
+ namedInsteadInAnswerText: z18.array(measurementPortfolioCountedNameSchema).max(MEASUREMENT_PORTFOLIO_ROW_EVIDENCE_LIMIT),
7240
+ /** Distinct names across those answers; more than returned means the list was cut. */
7241
+ namedInsteadInAnswerTextTotal: measurementDemoCountSchema,
7242
+ /**
7243
+ * Domains cited by this Property's stored answers in this run and class,
7244
+ * every engine included: each answer's stored domains plus the hosts of its
7245
+ * captured source URLs, and answers whose text was not captured count too.
7246
+ */
7247
+ citedDomains: z18.array(measurementPortfolioCountedDomainSchema).max(MEASUREMENT_PORTFOLIO_ROW_EVIDENCE_LIMIT),
7248
+ /** Distinct cited domains; more than returned means the list was cut. */
7249
+ citedDomainsTotal: measurementDemoCountSchema,
7250
+ /**
7251
+ * Deprecated: read `namedInsteadInAnswerText`. The same names in the same
7252
+ * order, kept for existing consumers. `occurrences` counts answers, one per
7253
+ * answer however it spells the name, exactly as `answers` does there.
7254
+ */
7255
+ recommendedInstead: z18.array(measurementPortfolioRecommendedInsteadSchema).max(MEASUREMENT_PORTFOLIO_ROW_EVIDENCE_LIMIT).meta({ deprecated: true, description: "Deprecated: read namedInsteadInAnswerText, which carries the same names in the same order. occurrences counts answers, exactly as answers does there." }),
7256
+ /** Deprecated: read `namedInsteadInAnswerTextTotal`, which it always equals. */
7257
+ recommendedInsteadTotal: measurementDemoCountSchema.meta({ deprecated: true, description: "Deprecated: read namedInsteadInAnswerTextTotal, which it always equals." }),
7258
+ /** Deprecated: true when `namedInsteadInAnswerTextTotal` exceeds the names returned. */
7259
+ recommendedInsteadTruncated: z18.boolean().meta({ deprecated: true, description: "Deprecated: true when namedInsteadInAnswerTextTotal exceeds the names returned in namedInsteadInAnswerText." })
7178
7260
  }).strict().superRefine((row, ctx) => {
7261
+ if (row.namedInsteadInAnswerText.length > row.namedInsteadInAnswerTextTotal) {
7262
+ ctx.addIssue({ code: z18.ZodIssueCode.custom, path: ["namedInsteadInAnswerTextTotal"], message: "Total cannot be smaller than the returned names" });
7263
+ }
7264
+ if (row.citedDomains.length > row.citedDomainsTotal) {
7265
+ ctx.addIssue({ code: z18.ZodIssueCode.custom, path: ["citedDomainsTotal"], message: "Total cannot be smaller than the returned domains" });
7266
+ }
7267
+ if (row.recommendedInsteadTotal !== row.namedInsteadInAnswerTextTotal) {
7268
+ ctx.addIssue({ code: z18.ZodIssueCode.custom, path: ["recommendedInsteadTotal"], message: "The deprecated total must equal namedInsteadInAnswerTextTotal" });
7269
+ }
7179
7270
  if (row.recommendedInstead.length > row.recommendedInsteadTotal) {
7180
7271
  ctx.addIssue({ code: z18.ZodIssueCode.custom, path: ["recommendedInsteadTotal"], message: "Total cannot be smaller than the returned replacements" });
7181
7272
  }
@@ -7183,24 +7274,46 @@ var measurementPortfolioWeakestPropertySchema = measurementDemoPropertySchema.ex
7183
7274
  ctx.addIssue({ code: z18.ZodIssueCode.custom, path: ["recommendedInsteadTruncated"], message: "Truncation must agree with the replacement total" });
7184
7275
  }
7185
7276
  });
7277
+ var measurementPortfolioWeakestTieSchema = z18.object({
7278
+ count: z18.number().int().min(2),
7279
+ mentionRate: z18.number(),
7280
+ citationRate: z18.number(),
7281
+ note: z18.literal(MEASUREMENT_PORTFOLIO_TIE_NOTE)
7282
+ }).strict();
7283
+ var measurementPortfolioAnswerSourcesSchema = z18.object({
7284
+ properties: measurementDemoCountSchema,
7285
+ answers: measurementDemoCountSchema,
7286
+ domains: z18.array(measurementPortfolioCountedDomainSchema).max(MEASUREMENT_PORTFOLIO_ANSWER_SOURCES_LIMIT),
7287
+ domainTotal: measurementDemoCountSchema
7288
+ }).strict().superRefine((sources, ctx) => {
7289
+ if (sources.domains.length > sources.domainTotal) {
7290
+ ctx.addIssue({ code: z18.ZodIssueCode.custom, path: ["domainTotal"], message: "Total cannot be smaller than the returned domains" });
7291
+ }
7292
+ if (sources.domains.some((row) => row.answers > sources.answers)) {
7293
+ ctx.addIssue({ code: z18.ZodIssueCode.custom, path: ["domains"], message: "A domain cannot be cited by more answers than the basis holds" });
7294
+ }
7295
+ });
7186
7296
  var measurementPortfolioMarketSchema = z18.object({
7187
7297
  groupKey: measurementV2StableKeySchema,
7188
7298
  label: measurementDemoLabelSchema,
7299
+ /** Null for a top-level market. */
7300
+ parentGroupKey: measurementV2StableKeySchema.nullable(),
7301
+ /** Direct child markets; read one with `groupKey` to list them. */
7302
+ childMarketCount: measurementDemoCountSchema,
7189
7303
  propertyCount: measurementDemoCountSchema,
7190
7304
  propertiesMentioned: measurementMetricValueSchema,
7191
7305
  mentionCoverage: measurementMetricValueSchema,
7192
7306
  citationCoverage: measurementMetricValueSchema
7193
7307
  }).strict();
7308
+ var measurementPortfolioRankedPropertySchema = measurementDemoPropertySchema.extend({
7309
+ ...measurementPortfolioPropertyContextShape,
7310
+ mentionCoverage: measurementMetricValueSchema.options[0],
7311
+ citationCoverage: measurementMetricValueSchema
7312
+ }).strict();
7194
7313
  var measurementPortfolioMentionRankingSchema = z18.object({
7195
7314
  eligiblePropertyCount: measurementDemoCountSchema,
7196
- strongest: z18.array(measurementDemoPropertySchema.extend({
7197
- mentionCoverage: measurementMetricValueSchema.options[0],
7198
- citationCoverage: measurementMetricValueSchema
7199
- }).strict()).max(50),
7200
- weakest: z18.array(measurementDemoPropertySchema.extend({
7201
- mentionCoverage: measurementMetricValueSchema.options[0],
7202
- citationCoverage: measurementMetricValueSchema
7203
- }).strict()).max(50),
7315
+ strongest: z18.array(measurementPortfolioRankedPropertySchema).max(50),
7316
+ weakest: z18.array(measurementPortfolioRankedPropertySchema).max(50),
7204
7317
  /** All excluded Properties in this scope, independent of the ranked list limit. */
7205
7318
  excluded: z18.array(measurementDemoPropertySchema.extend({
7206
7319
  reason: measurementMetricUnavailableReasonSchema
@@ -7217,23 +7330,37 @@ var measurementPortfolioSummaryResponseSchema = z18.object({
7217
7330
  }).strict(),
7218
7331
  measurement: measurementDemoRunMetadataSchema,
7219
7332
  queryClass: measurementQueryClassFilterSchema,
7333
+ /** Engines behind the displayed answers, after any provider filter. Empty before a run completes. */
7334
+ engines: z18.array(providerNameSchema),
7220
7335
  metrics: z18.object({
7221
7336
  propertiesMentioned: measurementMetricValueSchema,
7222
7337
  mentionCoverage: measurementMetricValueSchema,
7223
7338
  citationCoverage: measurementMetricValueSchema
7224
7339
  }).strict(),
7225
7340
  weakestProperties: z18.array(measurementPortfolioWeakestPropertySchema),
7341
+ /** Set when two or more Properties share the weakest row's rates; null otherwise. */
7342
+ tiedAtWeakest: measurementPortfolioWeakestTieSchema.nullable(),
7343
+ /** Null before a run completes. */
7344
+ weakestAnswerSources: measurementPortfolioAnswerSourcesSchema.nullable(),
7226
7345
  /** Descriptive mention ranking, using the response queryClass and scope; aggregate unavailability does not invalidate it. */
7227
7346
  mentionRanking: measurementPortfolioMentionRankingSchema,
7228
7347
  /**
7229
- * Every named market, worst-first. Empty when the request already narrowed to
7230
- * one group (a roll-up would only restate the scope) and when the plan defines
7231
- * no groups. Additive field.
7348
+ * Markets worst-first. By default one level: the top-level markets, or the
7349
+ * selected group's direct children when `groupKey` is set (empty when it has
7350
+ * none), capped at `limit`. `includeNestedMarkets` returns every market in
7351
+ * scope at every level, uncapped. Empty when the plan defines no groups.
7232
7352
  */
7233
7353
  markets: z18.array(measurementPortfolioMarketSchema),
7354
+ /** Markets at the returned level before `limit`; more than returned means the list was cut. */
7355
+ totalMarkets: measurementDemoCountSchema,
7356
+ marketsTruncated: z18.boolean(),
7234
7357
  totalProperties: measurementDemoCountSchema,
7235
7358
  truncated: z18.boolean()
7236
- }).strict();
7359
+ }).strict().superRefine((response, ctx) => {
7360
+ if (response.marketsTruncated !== response.markets.length < response.totalMarkets) {
7361
+ ctx.addIssue({ code: z18.ZodIssueCode.custom, path: ["marketsTruncated"], message: "Market truncation must agree with the market total" });
7362
+ }
7363
+ });
7237
7364
  var measurementPropertyQuestionsQuerySchema = z18.object({
7238
7365
  targetKey: measurementV2StableKeySchema,
7239
7366
  runId: measurementDemoFilterQueryShape.runId,
@@ -10899,6 +11026,7 @@ var runFillRefusalCodeSchema = z33.enum([
10899
11026
  "plan_revision_changed",
10900
11027
  "manifest_unreadable",
10901
11028
  "model_not_frozen",
11029
+ "model_retired",
10902
11030
  "provider_not_in_plan",
10903
11031
  "provider_nothing_missing",
10904
11032
  "provider_not_configured",
@@ -13055,6 +13183,12 @@ var sourceRankEntrySchema = z40.object({
13055
13183
  count: z40.number().int(),
13056
13184
  /** Share of the list's `totalCitedSlots`, 0..1 (4dp). */
13057
13185
  percentage: z40.number(),
13186
+ /**
13187
+ * Share of the list's `answerTotal` (every answer in scope, including answers
13188
+ * that cited nothing) that cite this domain, 0..1 (4dp). Optional only so an
13189
+ * older server's response still parses.
13190
+ */
13191
+ answerShare: z40.number().optional(),
13058
13192
  category: sourceCategorySchema,
13059
13193
  label: z40.string(),
13060
13194
  surfaceClass: surfaceClassSchema
@@ -13068,8 +13202,12 @@ var surfaceClassCountSchema = z40.object({
13068
13202
  domainCount: z40.number().int()
13069
13203
  });
13070
13204
  var rankedSourceListSchema = z40.object({
13071
- /** Total cited slots (grounding citations) counted in this scope. */
13205
+ /** Total cited slots in this scope: one per (answer, cited domain) pair. */
13072
13206
  totalCitedSlots: z40.number().int(),
13207
+ /** Answers in this scope, including answers that cited nothing. Denominator of `answerShare`. */
13208
+ answerTotal: z40.number().int().optional(),
13209
+ /** Answers in this scope whose stored source list names at least one domain. */
13210
+ answersWithSources: z40.number().int().optional(),
13073
13211
  /** Distinct domains in this scope. */
13074
13212
  domainTotal: z40.number().int(),
13075
13213
  /** Ranked domains, desc by count; truncated to the applied limit if any. */
@@ -13081,17 +13219,57 @@ var rankedSourceListSchema = z40.object({
13081
13219
  /** Surface-class roll-up over the FULL scope (not just `entries`). */
13082
13220
  bySurfaceClass: z40.array(surfaceClassCountSchema)
13083
13221
  });
13222
+ var sourceBreakdownQueryClassBasisSchema = z40.enum(["measurement-plan", "query-text"]);
13223
+ var sourceBreakdownQuerySchema = z40.object({
13224
+ /** One stored answer-visibility run. Omit to pool every run in the window. */
13225
+ runId: z40.string().trim().min(1).optional(),
13226
+ /**
13227
+ * Branded or non-brand answers only. With an active v2 measurement plan the
13228
+ * class comes from each run's frozen plan assignments; otherwise from the
13229
+ * project's brand-name classifier over the query text. `all` (the default)
13230
+ * pools both classes.
13231
+ */
13232
+ queryClass: queryClassFilterSchema.optional(),
13233
+ /** `false` omits the per-query breakdown (`byQuery`), which is large. Defaults to `true`. */
13234
+ includeByQuery: z40.enum(["true", "false", "1", "0"]).optional()
13235
+ });
13084
13236
  var sourceBreakdownDtoSchema = z40.object({
13085
- overall: z40.array(sourceCategoryCountSchema),
13086
- byQuery: z40.record(z40.string(), z40.array(sourceCategoryCountSchema)),
13087
13237
  /** Full ranked + classified cited-domain list across all providers (#675). */
13088
13238
  ranked: rankedSourceListSchema,
13089
13239
  /** Per-provider ranked + classified breakdown, keyed by provider name (#675). */
13090
13240
  byProvider: z40.record(z40.string(), rankedSourceListSchema),
13241
+ /**
13242
+ * Providers that answered in scope but whose answers name no resolvable
13243
+ * source. They are absent from `byProvider`; listed here so their absence is
13244
+ * never read as missing data.
13245
+ */
13246
+ providersWithoutSources: z40.array(z40.string()).optional(),
13247
+ /** Answers in scope after every filter, across all providers. */
13248
+ answerTotal: z40.number().int().optional(),
13249
+ /** Runs pooled into this response. More than one means several sweeps are pooled. */
13250
+ runCount: z40.number().int().optional(),
13251
+ /**
13252
+ * Answers the `queryClass` filter could not place in either class (a run with
13253
+ * no frozen v2 plan, an answer with no plan execution, or no query text).
13254
+ * They are excluded from every count. Zero when no class filter is applied.
13255
+ */
13256
+ unclassifiedAnswers: z40.number().int().optional(),
13257
+ /** Echo of the applied filters. */
13258
+ filters: z40.object({
13259
+ runId: z40.string().nullable(),
13260
+ queryClass: queryClassFilterSchema,
13261
+ /** Null when `queryClass` is `all` and no classification was applied. */
13262
+ queryClassBasis: z40.union([sourceBreakdownQueryClassBasisSchema, z40.null()]),
13263
+ includeByQuery: z40.boolean()
13264
+ }).optional(),
13091
13265
  runId: z40.string(),
13092
13266
  window: metricsWindowSchema,
13093
13267
  /** Applied ranked-list limit; null when the full list is returned. */
13094
- limit: z40.number().int().nullable()
13268
+ limit: z40.number().int().nullable(),
13269
+ /** Legacy category breakdown (top 5 domains per category). */
13270
+ overall: z40.array(sourceCategoryCountSchema),
13271
+ /** Per-query category breakdown keyed by current query text. Omitted with `includeByQuery=false`. */
13272
+ byQuery: z40.record(z40.string(), z40.array(sourceCategoryCountSchema)).optional()
13095
13273
  });
13096
13274
  var competitorLandscapeSurfaceClassSchema = z40.enum([
13097
13275
  "own",
@@ -13172,10 +13350,14 @@ var competitorLandscapeEvidenceSchema = z40.object({
13172
13350
  excludedNonCompletedResults: z40.number().int().nonnegative()
13173
13351
  }).strict();
13174
13352
  var COMPETITOR_LANDSCAPE_MODEL_GROUP_LIMIT = 50;
13353
+ var COMPETITOR_LANDSCAPE_OBSERVED_NAME_LIMIT = 50;
13175
13354
  var competitorLandscapeModelGroupSchema = z40.object({
13176
13355
  ...shareOfVoiceContextFields,
13177
13356
  comparison: z40.array(z40.object({ domain: z40.string(), mentions: z40.number().int().nonnegative() })).optional(),
13357
+ /** Names written in the answer text (not cited sources), top `COMPETITOR_LANDSCAPE_OBSERVED_NAME_LIMIT` by answer count. */
13178
13358
  observedNames: z40.array(z40.object({ name: z40.string(), answerCount: z40.number().int().nonnegative() })).optional(),
13359
+ /** Distinct observed names before the cap. Greater than `observedNames.length` when the list was cut. */
13360
+ observedNamesTotal: z40.number().int().nonnegative().optional(),
13179
13361
  provider: z40.string().trim().min(1),
13180
13362
  /** Null preserves historical observations with unknown requested model identity. */
13181
13363
  model: modelIdSchema.nullable(),
@@ -13200,7 +13382,10 @@ var competitorLandscapeModelComparisonSchema = z40.object({
13200
13382
  var competitorLandscapeResponseSchema = z40.object({
13201
13383
  ...shareOfVoiceContextFields,
13202
13384
  comparison: z40.array(z40.object({ domain: z40.string(), mentions: z40.number().int().nonnegative() })).optional(),
13385
+ /** Names written in the answer text (not cited sources), top `COMPETITOR_LANDSCAPE_OBSERVED_NAME_LIMIT` by answer count. */
13203
13386
  observedNames: z40.array(z40.object({ name: z40.string(), answerCount: z40.number().int().nonnegative() })).optional(),
13387
+ /** Distinct observed names before the cap. Greater than `observedNames.length` when the list was cut. */
13388
+ observedNamesTotal: z40.number().int().nonnegative().optional(),
13204
13389
  window: metricsWindowSchema,
13205
13390
  scope: competitorLandscapeScopeSchema,
13206
13391
  project: competitorLandscapeRowSchema,
@@ -19477,6 +19662,8 @@ export {
19477
19662
  effectiveBrandNames,
19478
19663
  projectConfigSchema,
19479
19664
  resolveConfigSpecQueries,
19665
+ resolveProviderModel,
19666
+ queryClassFilterSchema,
19480
19667
  compileQueryClassifier,
19481
19668
  MEASUREMENT_PLAN_V2_SCHEMA_VERSION,
19482
19669
  measurementV2UsageEdgeKey,
@@ -19550,6 +19737,10 @@ export {
19550
19737
  buildMeasurementRunManifestV1,
19551
19738
  measurementReportResponseSchema,
19552
19739
  measurementPropertyEvidenceResponseSchema,
19740
+ MEASUREMENT_PORTFOLIO_DEFAULT_LIMIT,
19741
+ MEASUREMENT_PORTFOLIO_ROW_EVIDENCE_LIMIT,
19742
+ MEASUREMENT_PORTFOLIO_ANSWER_SOURCES_LIMIT,
19743
+ MEASUREMENT_PORTFOLIO_TIE_NOTE,
19553
19744
  measurementPortfolioSummaryQuerySchema,
19554
19745
  measurementPortfolioSummaryResponseSchema,
19555
19746
  measurementPropertyQuestionsQuerySchema,
@@ -19912,9 +20103,11 @@ export {
19912
20103
  normalizeModelId,
19913
20104
  modelIdsEquivalent,
19914
20105
  brandMetricsDtoSchema,
20106
+ sourceBreakdownQuerySchema,
19915
20107
  sourceBreakdownDtoSchema,
19916
20108
  competitorLandscapeQuerySchema,
19917
20109
  COMPETITOR_LANDSCAPE_MODEL_GROUP_LIMIT,
20110
+ COMPETITOR_LANDSCAPE_OBSERVED_NAME_LIMIT,
19918
20111
  competitorLandscapeResponseSchema,
19919
20112
  parseWindow,
19920
20113
  windowCutoff,
@@ -4,14 +4,14 @@ import {
4
4
  installSkills,
5
5
  loadConfigRaw,
6
6
  saveConfigPatch
7
- } from "./chunk-SPCEXW3B.js";
7
+ } from "./chunk-5FKR2K76.js";
8
8
  import {
9
9
  PACKAGE_VERSION
10
- } from "./chunk-YHKKCXGY.js";
10
+ } from "./chunk-XBGPHZKA.js";
11
11
  import {
12
12
  SKILL_MANIFEST_FILENAME,
13
13
  SkillsClients
14
- } from "./chunk-WLL7Q7JD.js";
14
+ } from "./chunk-QF7SY7AF.js";
15
15
 
16
16
  // src/skills-autosync.ts
17
17
  import fs from "fs";