@canonry/canonry 5.28.1 → 5.29.1

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 (33) hide show
  1. package/assets/assets/{AuditHistoryPanel-CWd9UN6L.js → AuditHistoryPanel-B_H7nIp7.js} +1 -1
  2. package/assets/assets/{BacklinksPage-B2gPTzyE.js → BacklinksPage-rhms6z2S.js} +1 -1
  3. package/assets/assets/{HistoryPage-xtkG8SZN.js → HistoryPage-CWPETgrG.js} +1 -1
  4. package/assets/assets/MeasurementPropertyPage-D9-54Je9.js +1 -0
  5. package/assets/assets/ProjectPage-eNVzxsZW.js +8 -0
  6. package/assets/assets/{RunRow-DnSo7Nle.js → RunRow-DQPW7FIF.js} +1 -1
  7. package/assets/assets/{RunsPage-FAEuo4Ra.js → RunsPage-BOM_RkNi.js} +1 -1
  8. package/assets/assets/{SettingsPage-C4OZ1HB9.js → SettingsPage-BDnT6wtM.js} +1 -1
  9. package/assets/assets/SiteHealthSection-lcZA1XpM.js +4 -0
  10. package/assets/assets/{TrafficPage-D03S6xF6.js → TrafficPage-D4nGSfXx.js} +2 -2
  11. package/assets/assets/{TrafficSourceDetailPage-DBu6oFFK.js → TrafficSourceDetailPage-CvZcCbic.js} +1 -1
  12. package/assets/assets/{extract-error-message-BuH2CCaJ.js → extract-error-message-BJ3f0StM.js} +1 -1
  13. package/assets/assets/index-Cncchurw.js +86 -0
  14. package/assets/assets/{react-sigma_core.esm.min-CxwZsgxR.js → react-sigma_core.esm.min-c7qzyLLe.js} +1 -1
  15. package/assets/assets/{v2-overview-adapter-DTCKxzZT.js → v2-overview-adapter-Dsd6dWtE.js} +1 -1
  16. package/assets/index.html +1 -1
  17. package/dist/{chunk-DX2JUC5H.js → chunk-ASYPQYVV.js} +3 -3
  18. package/dist/{chunk-KVQHG3WB.js → chunk-FKL5EGOW.js} +6302 -5914
  19. package/dist/{chunk-EP4STEPI.js → chunk-N2SVFXOB.js} +164 -96
  20. package/dist/{chunk-ONTEFAA7.js → chunk-PTTVDWMN.js} +57 -3
  21. package/dist/{chunk-7RKCDOWO.js → chunk-RHZKOXDZ.js} +263 -190
  22. package/dist/{chunk-MPICT6V7.js → chunk-WL2SHCPU.js} +3 -3
  23. package/dist/{chunk-FNGITGDF.js → chunk-XWBQWAVE.js} +2 -2
  24. package/dist/cli.js +134 -123
  25. package/dist/{demo-server-HWWIMGD6.js → demo-server-VGUIDC5T.js} +24 -32
  26. package/dist/index.js +6 -6
  27. package/dist/{intelligence-service-6LDMVI66.js → intelligence-service-IQA4U3RA.js} +2 -2
  28. package/dist/mcp.js +4 -4
  29. package/package.json +12 -12
  30. package/assets/assets/MeasurementPropertyPage-DxIMU3_T.js +0 -1
  31. package/assets/assets/ProjectPage-CMAFZq_s.js +0 -8
  32. package/assets/assets/SiteHealthSection-BzMxlz8-.js +0 -4
  33. package/assets/assets/index-Ba-Zs45G.js +0 -86
@@ -17,19 +17,21 @@ import {
17
17
  resolveOperatorApiKeyIds,
18
18
  runWithUsageTags,
19
19
  saveConfigPatch
20
- } from "./chunk-FNGITGDF.js";
20
+ } from "./chunk-XWBQWAVE.js";
21
21
  import {
22
+ computeFactorAverages,
22
23
  deleteSiteCrawlGraphLayout,
23
24
  persistSiteCrawlGraphLayout,
24
- prepareSiteCrawlGraphLayout
25
- } from "./chunk-ONTEFAA7.js";
25
+ prepareSiteCrawlGraphLayout,
26
+ recordedSharePct
27
+ } from "./chunk-PTTVDWMN.js";
26
28
  import {
27
29
  CanonryMcpToolNames,
28
30
  CliError,
29
31
  PACKAGE_VERSION,
30
32
  canonryMcpTools,
31
33
  isMachineFormat
32
- } from "./chunk-MPICT6V7.js";
34
+ } from "./chunk-WL2SHCPU.js";
33
35
  import {
34
36
  CC_CACHE_DIR,
35
37
  DUCKDB_SPEC,
@@ -62,6 +64,7 @@ import {
62
64
  bingCoverageSnapshots,
63
65
  bingUrlInspections,
64
66
  buildLocationProfileFields,
67
+ buildOpenApiDocument,
65
68
  captureSimpleMeasurementDefinition,
66
69
  ccReleasePaths,
67
70
  ccReleaseSyncs,
@@ -200,7 +203,7 @@ import {
200
203
  siteLivenessState,
201
204
  toAlertView,
202
205
  usageCounters
203
- } from "./chunk-7RKCDOWO.js";
206
+ } from "./chunk-RHZKOXDZ.js";
204
207
  import {
205
208
  AGENT_MEMORY_VALUE_MAX_BYTES,
206
209
  AGENT_NONE,
@@ -241,6 +244,7 @@ import {
241
244
  ProviderBatchSubmitError,
242
245
  ProviderDispatchModes,
243
246
  ProviderNames,
247
+ RATIO_UNIT_META_KEY,
244
248
  ROUTE_CAPABLE_CITED_URL_PROVIDERS,
245
249
  RUN_FILL_PROVIDER_BREAKER,
246
250
  ResearchQueryStatuses,
@@ -311,6 +315,7 @@ import {
311
315
  filterCapturedCitedUrls,
312
316
  forbidden,
313
317
  formatIsoDateInTimeZone,
318
+ formatPercent,
314
319
  formatRunErrorOneLine,
315
320
  frameAncestorsHeaderValue,
316
321
  googleAdsAccessibleCustomerDtoSchema,
@@ -357,8 +362,10 @@ import {
357
362
  parseMeasurementRunManifestV1,
358
363
  parseOriginList,
359
364
  parseRunError,
365
+ percentOf,
360
366
  providerError,
361
367
  providerSupportsLocationContext,
368
+ ratioUnitSchema,
362
369
  registrableDomain,
363
370
  reportMonthsForDoctor,
364
371
  resolveNegativeReviewMaxStars,
@@ -385,7 +392,7 @@ import {
385
392
  visibilityReportRequestSchema,
386
393
  winnabilityClassLabel,
387
394
  withRetry
388
- } from "./chunk-KVQHG3WB.js";
395
+ } from "./chunk-FKL5EGOW.js";
389
396
 
390
397
  // src/runtime-context.ts
391
398
  function cliRuntimeContext(env = process.env, stdio = process) {
@@ -1734,8 +1741,8 @@ function stableStringify(value) {
1734
1741
  if (typeof value !== "object") throw new TypeError("Value is not JSON-serializable");
1735
1742
  if (Array.isArray(value)) return `[${value.map(stableStringify).join(",")}]`;
1736
1743
  const object = value;
1737
- const members = Object.keys(object).filter((key) => object[key] !== void 0).sort().map((key) => `${JSON.stringify(key)}:${stableStringify(object[key])}`);
1738
- return `{${members.join(",")}}`;
1744
+ const members2 = Object.keys(object).filter((key) => object[key] !== void 0).sort().map((key) => `${JSON.stringify(key)}:${stableStringify(object[key])}`);
1745
+ return `{${members2.join(",")}}`;
1739
1746
  }
1740
1747
  function checksumJson(value) {
1741
1748
  return crypto2.createHash("sha256").update(stableStringify(value)).digest("hex");
@@ -5671,7 +5678,7 @@ var CDPConnectionManager = class {
5671
5678
  }
5672
5679
  };
5673
5680
  function sleep(ms) {
5674
- return new Promise((resolve) => setTimeout(resolve, ms));
5681
+ return new Promise((resolve2) => setTimeout(resolve2, ms));
5675
5682
  }
5676
5683
  async function waitForStabilization(client, selector, opts = {}) {
5677
5684
  const pollInterval = opts.pollIntervalMs ?? 500;
@@ -5894,7 +5901,7 @@ async function checkAuthState(client) {
5894
5901
  return !!result2.value;
5895
5902
  }
5896
5903
  function sleep2(ms) {
5897
- return new Promise((resolve) => setTimeout(resolve, ms));
5904
+ return new Promise((resolve2) => setTimeout(resolve2, ms));
5898
5905
  }
5899
5906
 
5900
5907
  // ../provider-cdp/src/screenshot.ts
@@ -7367,7 +7374,7 @@ function nonBlank(value) {
7367
7374
  return trimmed ? trimmed : void 0;
7368
7375
  }
7369
7376
  function resolveBuildCommit(env = process.env) {
7370
- const embedded = true ? "a613f8145e4548393912ffe1a53233abaad1ce8e" : void 0;
7377
+ const embedded = true ? "0d21d82ed5ceafcb71d46bb38e37ed6c2825e50b" : void 0;
7371
7378
  return nonBlank(embedded) ?? nonBlank(env.CANONRY_COMMIT);
7372
7379
  }
7373
7380
  function resolveInstanceIdentity(env = process.env) {
@@ -7474,7 +7481,7 @@ var ProviderExecutionGate = class {
7474
7481
  this.inFlight++;
7475
7482
  return;
7476
7483
  }
7477
- await new Promise((resolve) => this.waiters.push(resolve));
7484
+ await new Promise((resolve2) => this.waiters.push(resolve2));
7478
7485
  this.inFlight++;
7479
7486
  }
7480
7487
  release() {
@@ -7484,8 +7491,8 @@ var ProviderExecutionGate = class {
7484
7491
  async waitForRateLimit() {
7485
7492
  let releaseChain;
7486
7493
  const previousChain = this.rateLimitChain;
7487
- this.rateLimitChain = new Promise((resolve) => {
7488
- releaseChain = resolve;
7494
+ this.rateLimitChain = new Promise((resolve2) => {
7495
+ releaseChain = resolve2;
7489
7496
  });
7490
7497
  await previousChain;
7491
7498
  try {
@@ -7493,7 +7500,7 @@ var ProviderExecutionGate = class {
7493
7500
  const windowStart = now - 6e4;
7494
7501
  while (this.window.length > 0 && this.window[0] < windowStart) this.window.shift();
7495
7502
  if (this.window.length >= this.maxPerMinute) {
7496
- await new Promise((resolve) => setTimeout(resolve, this.window[0] + 6e4 - now + 50));
7503
+ await new Promise((resolve2) => setTimeout(resolve2, this.window[0] + 6e4 - now + 50));
7497
7504
  const nextWindowStart = Date.now() - 6e4;
7498
7505
  while (this.window.length > 0 && this.window[0] < nextWindowStart) this.window.shift();
7499
7506
  }
@@ -11302,7 +11309,7 @@ function isRetryableGscInspectError(err) {
11302
11309
  return isRetryableHttpError(err);
11303
11310
  }
11304
11311
  function defaultSleep(ms) {
11305
- return new Promise((resolve) => setTimeout(resolve, ms));
11312
+ return new Promise((resolve2) => setTimeout(resolve2, ms));
11306
11313
  }
11307
11314
  async function inspectUrlsPaced(urls, cb, deps) {
11308
11315
  const sleep3 = deps.sleep ?? defaultSleep;
@@ -12111,7 +12118,7 @@ var EMBED_RETRY_MAX_RETRIES = 3;
12111
12118
  var EMBED_RETRY_MAX_DELAY_MS = 1e4;
12112
12119
  var EMBED_ATTEMPT_TIMEOUT_MS = 6e4;
12113
12120
  function withAttemptTimeout(promise, timeoutMs, label) {
12114
- return new Promise((resolve, reject) => {
12121
+ return new Promise((resolve2, reject) => {
12115
12122
  const timer = setTimeout(
12116
12123
  () => reject(new Error(`${label} timed out after ${timeoutMs}ms`)),
12117
12124
  timeoutMs
@@ -12119,7 +12126,7 @@ function withAttemptTimeout(promise, timeoutMs, label) {
12119
12126
  promise.then(
12120
12127
  (value) => {
12121
12128
  clearTimeout(timer);
12122
- resolve(value);
12129
+ resolve2(value);
12123
12130
  },
12124
12131
  (err) => {
12125
12132
  clearTimeout(timer);
@@ -12645,7 +12652,7 @@ async function requestPinnedSiteAuditRoot(target, options) {
12645
12652
  throwIfAborted(options.signal);
12646
12653
  const secure = target.url.protocol === "https:";
12647
12654
  const requestOptions = buildSiteAuditRootRequestOptions(target);
12648
- return await new Promise((resolve, reject) => {
12655
+ return await new Promise((resolve2, reject) => {
12649
12656
  let settled = false;
12650
12657
  let abortListener;
12651
12658
  const cleanup = () => {
@@ -12656,7 +12663,7 @@ async function requestPinnedSiteAuditRoot(target, options) {
12656
12663
  if (settled) return;
12657
12664
  settled = true;
12658
12665
  cleanup();
12659
- resolve(response);
12666
+ resolve2(response);
12660
12667
  };
12661
12668
  const fail = (error) => {
12662
12669
  if (settled) return;
@@ -12813,7 +12820,7 @@ function clampSiteAuditEdgeLimit(limit) {
12813
12820
  return Math.max(1, Math.min(SITE_AUDIT_MAX_EDGE_LIMIT, Math.floor(limit)));
12814
12821
  }
12815
12822
  function toPageFactor(factor) {
12816
- return { id: factor.id, name: factor.name, weight: factor.weight, score: factor.score };
12823
+ return { id: factor.id, name: factor.name, weight: factor.weight, score: factor.score, sharePct: recordedSharePct(factor) };
12817
12824
  }
12818
12825
  function toCrawlAuditFactor(factor) {
12819
12826
  return {
@@ -12831,34 +12838,6 @@ function crawlAuditFields(audit) {
12831
12838
  criticalDefects: audit.criticalDefects
12832
12839
  };
12833
12840
  }
12834
- function computeFactorAverages(pages) {
12835
- const byId = /* @__PURE__ */ new Map();
12836
- for (const page of pages) {
12837
- if (!page.audit) continue;
12838
- for (const factor of page.audit.factors) {
12839
- const current = byId.get(factor.id) ?? { name: factor.name, weight: factor.weight, scores: [], pass: 0, partial: 0, fail: 0 };
12840
- byId.set(factor.id, current);
12841
- current.scores.push(factor.score);
12842
- const status = factorStatusFromScore(factor.score);
12843
- if (status === "pass") current.pass++;
12844
- else if (status === "partial") current.partial++;
12845
- else current.fail++;
12846
- }
12847
- }
12848
- return [...byId.entries()].map(([id, value]) => {
12849
- const avgScore = Math.round(value.scores.reduce((sum, score) => sum + score, 0) / value.scores.length);
12850
- return {
12851
- id,
12852
- name: value.name,
12853
- weight: value.weight,
12854
- avgScore,
12855
- status: factorStatusFromScore(avgScore),
12856
- pagesPassing: value.pass,
12857
- pagesPartial: value.partial,
12858
- pagesFailing: value.fail
12859
- };
12860
- }).sort((a, b) => b.weight - a.weight || a.name.localeCompare(b.name));
12861
- }
12862
12841
  function pagePath(page) {
12863
12842
  if (page.path) return page.path;
12864
12843
  try {
@@ -12918,7 +12897,7 @@ function toLegacyIssue(summary, totalPages) {
12918
12897
  avgScore: summary.avgScore,
12919
12898
  affectedPages: affected,
12920
12899
  totalPages,
12921
- affectedPct: totalPages > 0 ? Math.round(affected / totalPages * 100) : 0,
12900
+ affectedPct: percentOf(affected, totalPages) ?? 0,
12922
12901
  topRecommendations: []
12923
12902
  };
12924
12903
  }
@@ -14005,7 +13984,7 @@ function readStoredGroundingSources(rawResponse) {
14005
13984
  return result2;
14006
13985
  }
14007
13986
  async function backfillInsightsCommand(project, opts) {
14008
- const { IntelligenceService: IntelligenceService2 } = await import("./intelligence-service-6LDMVI66.js");
13987
+ const { IntelligenceService: IntelligenceService2 } = await import("./intelligence-service-IQA4U3RA.js");
14009
13988
  const config = loadConfig();
14010
13989
  const db = createClient(config.database);
14011
13990
  migrate(db);
@@ -16044,7 +16023,7 @@ var Notifier = class {
16044
16023
  }
16045
16024
  }
16046
16025
  if (attempt < maxRetries - 1) {
16047
- await new Promise((resolve) => setTimeout(resolve, delays[attempt]));
16026
+ await new Promise((resolve2) => setTimeout(resolve2, delays[attempt]));
16048
16027
  }
16049
16028
  }
16050
16029
  return false;
@@ -16600,6 +16579,92 @@ import { Type as Type3 } from "@sinclair/typebox";
16600
16579
  // src/agent/mcp-to-agent-tool.ts
16601
16580
  import { Type as Type2 } from "@sinclair/typebox";
16602
16581
  import { randomUUID } from "crypto";
16582
+
16583
+ // src/agent/tool-result-units.ts
16584
+ var SUCCESS_STATUSES = ["200", "201", "202"];
16585
+ var MAX_DEPTH = 40;
16586
+ var MAX_REF_HOPS = 8;
16587
+ var cachedDocument;
16588
+ function openApiDocument() {
16589
+ cachedDocument ??= buildOpenApiDocument();
16590
+ return cachedDocument;
16591
+ }
16592
+ function responseComponents() {
16593
+ return openApiDocument().components?.schemas ?? {};
16594
+ }
16595
+ function responseSchemasFor(operations) {
16596
+ const paths = openApiDocument().paths;
16597
+ return operations.flatMap((operation) => {
16598
+ const space = operation.indexOf(" ");
16599
+ if (space < 0) return [];
16600
+ const responses = paths[operation.slice(space + 1)]?.[operation.slice(0, space).toLowerCase()]?.responses;
16601
+ const schema = SUCCESS_STATUSES.map((status) => responses?.[status]?.content?.["application/json"]?.schema).find(Boolean);
16602
+ return schema ? [schema] : [];
16603
+ });
16604
+ }
16605
+ function isRecord3(value) {
16606
+ return value !== null && typeof value === "object" && !Array.isArray(value);
16607
+ }
16608
+ function resolve(schema, components) {
16609
+ let current = schema;
16610
+ for (let hop = 0; hop < MAX_REF_HOPS && typeof current.$ref === "string"; hop++) {
16611
+ const next = components[current.$ref.replace("#/components/schemas/", "")];
16612
+ if (!next) break;
16613
+ current = next;
16614
+ }
16615
+ return current;
16616
+ }
16617
+ function members(schema) {
16618
+ return ["allOf", "anyOf", "oneOf"].flatMap((key) => Array.isArray(schema[key]) ? schema[key] : []);
16619
+ }
16620
+ function unitOf(schema, components) {
16621
+ const own = ratioUnitSchema.safeParse(schema[RATIO_UNIT_META_KEY]);
16622
+ if (own.success) return own.data;
16623
+ for (const member of members(schema)) {
16624
+ const unit = unitOf(resolve(member, components), components);
16625
+ if (unit) return unit;
16626
+ }
16627
+ return void 0;
16628
+ }
16629
+ function render(schema, value, components, depth) {
16630
+ if (depth > MAX_DEPTH) return value;
16631
+ const node = resolve(schema, components);
16632
+ if (typeof value === "number") {
16633
+ const unit = unitOf(node, components);
16634
+ return unit ? formatPercent(value, unit) : value;
16635
+ }
16636
+ let current = value;
16637
+ for (const member of members(node)) current = render(member, current, components, depth + 1);
16638
+ if (Array.isArray(current) && isRecord3(node.items)) {
16639
+ const items = node.items;
16640
+ let changed = false;
16641
+ const out = current.map((item) => {
16642
+ const rendered = render(items, item, components, depth + 1);
16643
+ if (rendered !== item) changed = true;
16644
+ return rendered;
16645
+ });
16646
+ return changed ? out : current;
16647
+ }
16648
+ if (isRecord3(current)) {
16649
+ const properties = isRecord3(node.properties) ? node.properties : {};
16650
+ const extra = isRecord3(node.additionalProperties) ? node.additionalProperties : void 0;
16651
+ let changed = false;
16652
+ const out = {};
16653
+ for (const [key, child] of Object.entries(current)) {
16654
+ const childSchema = properties[key] ?? extra;
16655
+ const rendered = childSchema ? render(childSchema, child, components, depth + 1) : child;
16656
+ if (rendered !== child) changed = true;
16657
+ out[key] = rendered;
16658
+ }
16659
+ return changed ? out : current;
16660
+ }
16661
+ return current;
16662
+ }
16663
+ function renderRatioUnits(schema, value, components = {}) {
16664
+ return schema ? render(schema, value, components, 0) : value;
16665
+ }
16666
+
16667
+ // src/agent/mcp-to-agent-tool.ts
16603
16668
  var MAX_TOOL_RESULT_CHARS = 2e4;
16604
16669
  var TRUNCATION_NOTE = "... (truncated, result too large)";
16605
16670
  var TRUNCATION_SUMMARY_KEY = "__truncation";
@@ -16616,7 +16681,7 @@ var MAX_PARTIAL_NOTES = 12;
16616
16681
  function serializeResult(value) {
16617
16682
  return JSON.stringify(value);
16618
16683
  }
16619
- function isRecord3(value) {
16684
+ function isRecord4(value) {
16620
16685
  return !!value && typeof value === "object" && !Array.isArray(value);
16621
16686
  }
16622
16687
  function keptSummary(counts, cursors = {}) {
@@ -16671,7 +16736,7 @@ function partialLists(root) {
16671
16736
  if (count3.count <= rows.length) continue;
16672
16737
  notes.push([label, `${rows.length} of ${count3.text}`]);
16673
16738
  noted = true;
16674
- } else if (ownFlag === true || object.truncated === true && typeof ownFlag !== "boolean" && (lists.length === 1 || rows.some(isRecord3))) {
16739
+ } else if (ownFlag === true || object.truncated === true && typeof ownFlag !== "boolean" && (lists.length === 1 || rows.some(isRecord4))) {
16675
16740
  notes.push([label, `${rows.length} shown; the tool cut this list`]);
16676
16741
  noted = true;
16677
16742
  }
@@ -16680,14 +16745,14 @@ function partialLists(root) {
16680
16745
  if (object.truncated === true && !noted) notes.push([path9 || "(root)", "the tool cut the lists here"]);
16681
16746
  if (depth >= MAX_PARTIAL_DEPTH || notes.length >= MAX_PARTIAL_NOTES) return;
16682
16747
  for (const [key, value] of Object.entries(object)) {
16683
- if (!key.startsWith("__") && isRecord3(value)) visit(value, path9 ? `${path9}.${key}` : key, depth + 1);
16748
+ if (!key.startsWith("__") && isRecord4(value)) visit(value, path9 ? `${path9}.${key}` : key, depth + 1);
16684
16749
  }
16685
16750
  };
16686
16751
  visit(root, "", 1);
16687
16752
  return notes.length > 0 ? Object.fromEntries(notes.slice(0, MAX_PARTIAL_NOTES)) : void 0;
16688
16753
  }
16689
16754
  function withPartialLists(value) {
16690
- if (!isRecord3(value) || typeof value.toJSON === "function") return value;
16755
+ if (!isRecord4(value) || typeof value.toJSON === "function") return value;
16691
16756
  const hadNote = Object.hasOwn(value, PARTIAL_LISTS_KEY);
16692
16757
  const notes = partialLists(value);
16693
16758
  if (!notes && !hadNote) return value;
@@ -16720,11 +16785,11 @@ function largestFitting(max, fits) {
16720
16785
  }
16721
16786
  return low;
16722
16787
  }
16723
- function trimRowsToFit(rows, render) {
16788
+ function trimRowsToFit(rows, render2) {
16724
16789
  if (rows.length === 0) return [];
16725
16790
  const all = rows.slice();
16726
- if (fitsCap(render(all))) return all;
16727
- return rows.slice(0, largestFitting(rows.length - 1, (count3) => fitsCap(render(rows.slice(0, count3)))));
16791
+ if (fitsCap(render2(all))) return all;
16792
+ return rows.slice(0, largestFitting(rows.length - 1, (count3) => fitsCap(render2(rows.slice(0, count3)))));
16728
16793
  }
16729
16794
  function listTrimmer(lists) {
16730
16795
  const owners = /* @__PURE__ */ new Map();
@@ -16741,7 +16806,7 @@ function listTrimmer(lists) {
16741
16806
  hadTruncated: Object.hasOwn(owner, "__truncated"),
16742
16807
  priorTruncated: owner.__truncated,
16743
16808
  previous,
16744
- priorOmitted: isRecord3(previous) ? previous : void 0
16809
+ priorOmitted: isRecord4(previous) ? previous : void 0
16745
16810
  };
16746
16811
  });
16747
16812
  return (counts) => {
@@ -16777,12 +16842,12 @@ function collectCollections(root) {
16777
16842
  if (Array.isArray(value)) {
16778
16843
  let records = false;
16779
16844
  for (const row of value) {
16780
- if (!isRecord3(row)) continue;
16845
+ if (!isRecord4(row)) continue;
16781
16846
  records = true;
16782
16847
  visit(row, `${valuePath}[]`, true);
16783
16848
  }
16784
16849
  if (value.length > 0) found.push({ path: valuePath, nested, records, owner: object, key, rows: value });
16785
- } else if (isRecord3(value)) {
16850
+ } else if (isRecord4(value)) {
16786
16851
  visit(value, valuePath, nested);
16787
16852
  }
16788
16853
  }
@@ -16819,8 +16884,8 @@ function currentSummary(root, owned) {
16819
16884
  counts.set(list.path, count3);
16820
16885
  noteCursor(object, path9, list.path, value.length, list.rows.length, cursors);
16821
16886
  }
16822
- for (const row of value) if (isRecord3(row)) visit(row, `${valuePath}[]`);
16823
- } else if (isRecord3(value)) {
16887
+ for (const row of value) if (isRecord4(row)) visit(row, `${valuePath}[]`);
16888
+ } else if (isRecord4(value)) {
16824
16889
  visit(value, valuePath);
16825
16890
  }
16826
16891
  }
@@ -16833,7 +16898,7 @@ function emptiedFloorChars(root) {
16833
16898
  }
16834
16899
  function trimNestedArrays(full) {
16835
16900
  const copy = JSON.parse(full);
16836
- if (!isRecord3(copy)) return void 0;
16901
+ if (!isRecord4(copy)) return void 0;
16837
16902
  copy.__truncated = true;
16838
16903
  copy[TRUNCATION_SUMMARY_KEY] = keptSummary(/* @__PURE__ */ new Map());
16839
16904
  if (emptiedFloorChars(copy) > MAX_TOOL_RESULT_CHARS) return void 0;
@@ -16853,26 +16918,26 @@ function trimNestedArrays(full) {
16853
16918
  ), Infinity);
16854
16919
  const trim = listTrimmer(lists);
16855
16920
  let spent = 0;
16856
- const render = () => {
16921
+ const render2 = () => {
16857
16922
  trim(lists.map((_, index) => capOf(index)));
16858
16923
  copy[TRUNCATION_SUMMARY_KEY] = currentSummary(copy, owned);
16859
16924
  const text = serializeResult(withPartialLists(copy));
16860
16925
  spent += text.length;
16861
16926
  return text;
16862
16927
  };
16863
- const fits = () => spent <= TRUNCATION_SERIALIZE_BUDGET_CHARS && fitsCap(render());
16864
- const members = (stage) => lists.flatMap((_, index) => stagesOf[index].includes(stage) ? [index] : []);
16928
+ const fits = () => spent <= TRUNCATION_SERIALIZE_BUDGET_CHARS && fitsCap(render2());
16929
+ const members2 = (stage) => lists.flatMap((_, index) => stagesOf[index].includes(stage) ? [index] : []);
16865
16930
  const longest = (indexes) => indexes.reduce((max, index) => Math.max(max, lists[index].rows.length), 0);
16866
- let out = render();
16931
+ let out = render2();
16867
16932
  let fittedAt = -1;
16868
16933
  for (let stage = 0; stage < TRIM_STAGES.length && !fitsCap(out); stage++) {
16869
16934
  if (spent > TRUNCATION_SERIALIZE_BUDGET_CHARS) return void 0;
16870
16935
  const { floor } = TRIM_STAGES[stage];
16871
- const indexes = members(stage);
16936
+ const indexes = members2(stage);
16872
16937
  const top = longest(indexes);
16873
16938
  if (top <= floor) continue;
16874
16939
  levels[stage] = floor;
16875
- out = render();
16940
+ out = render2();
16876
16941
  if (!fitsCap(out)) continue;
16877
16942
  fittedAt = stage;
16878
16943
  const level = floor + largestFitting(top - floor - 1, (n) => {
@@ -16886,25 +16951,25 @@ function trimNestedArrays(full) {
16886
16951
  return fits();
16887
16952
  });
16888
16953
  boosted = { stage, lists: new Set(cut.slice(0, extra)) };
16889
- out = render();
16954
+ out = render2();
16890
16955
  }
16891
16956
  if (!fitsCap(out)) return void 0;
16892
16957
  for (let stage = fittedAt - 1; stage >= 0; stage--) {
16893
16958
  const floor = levels[stage];
16894
- const top = longest(members(stage));
16959
+ const top = longest(members2(stage));
16895
16960
  if (floor === Infinity || top <= floor) continue;
16896
16961
  levels[stage] = floor + largestFitting(top - floor, (n) => {
16897
16962
  levels[stage] = floor + n;
16898
16963
  return fits();
16899
16964
  });
16900
16965
  }
16901
- out = render();
16966
+ out = render2();
16902
16967
  return fitsCap(out) ? out : void 0;
16903
16968
  }
16904
16969
  function keptRowTotal(serialized) {
16905
16970
  const count3 = (value) => {
16906
16971
  if (Array.isArray(value)) return value.length;
16907
- if (!isRecord3(value)) return 0;
16972
+ if (!isRecord4(value)) return 0;
16908
16973
  return Object.entries(value).reduce((sum, [key, child]) => key.startsWith("__") ? sum : sum + count3(child), 0);
16909
16974
  };
16910
16975
  try {
@@ -16916,9 +16981,9 @@ function keptRowTotal(serialized) {
16916
16981
  function hasOtherLists(value, primary) {
16917
16982
  if (Array.isArray(value)) {
16918
16983
  if (value !== primary && value.length > 0) return true;
16919
- return value.some((row) => (isRecord3(row) || Array.isArray(row)) && hasOtherLists(row, primary));
16984
+ return value.some((row) => (isRecord4(row) || Array.isArray(row)) && hasOtherLists(row, primary));
16920
16985
  }
16921
- return isRecord3(value) && Object.values(value).some((child) => hasOtherLists(child, primary));
16986
+ return isRecord4(value) && Object.values(value).some((child) => hasOtherLists(child, primary));
16922
16987
  }
16923
16988
  function shortSegment(key) {
16924
16989
  return key.length > MAX_SUMMARY_SEGMENT_CHARS ? `${key.slice(0, MAX_SUMMARY_SEGMENT_CHARS)}...` : key;
@@ -17038,20 +17103,20 @@ function truncateToolResult(details) {
17038
17103
  if (full.length <= MAX_TOOL_RESULT_CHARS) return full;
17039
17104
  if (full.length > MAX_STRUCTURED_TRUNCATION_CHARS) return markedSlice(full, annotated);
17040
17105
  if (Array.isArray(details)) {
17041
- const render = (rows) => serializeResult({
17106
+ const render2 = (rows) => serializeResult({
17042
17107
  items: rows,
17043
17108
  __truncated: true,
17044
17109
  __omittedRows: details.length - rows.length,
17045
17110
  [TRUNCATION_SUMMARY_KEY]: keptSummary(/* @__PURE__ */ new Map([["items", { kept: rows.length, total: details.length }]]))
17046
17111
  });
17047
- return render(trimRowsToFit(details, render));
17112
+ return render2(trimRowsToFit(details, render2));
17048
17113
  }
17049
17114
  if (details && typeof details === "object") {
17050
17115
  const obj = details;
17051
17116
  const arrayKey = largestArrayKey(obj);
17052
17117
  if (!arrayKey) return trimNestedArrays(full) ?? markedSlice(full, annotated);
17053
17118
  const rows = obj[arrayKey];
17054
- const render = (kept) => {
17119
+ const render2 = (kept) => {
17055
17120
  const cursors = {};
17056
17121
  noteCursor(obj, "", arrayKey, kept.length, rows.length, cursors);
17057
17122
  return serializeResult(withPartialLists({
@@ -17062,16 +17127,18 @@ function truncateToolResult(details) {
17062
17127
  [TRUNCATION_SUMMARY_KEY]: keptSummary(/* @__PURE__ */ new Map([[arrayKey, { kept: kept.length, total: rows.length }]]), cursors)
17063
17128
  }));
17064
17129
  };
17065
- const out = render(trimRowsToFit(rows, render));
17130
+ const out = render2(trimRowsToFit(rows, render2));
17066
17131
  const nested = !fitsCap(out) || hasOtherLists(obj, rows) ? trimNestedArrays(full) : void 0;
17067
17132
  if (fitsCap(out) && (nested === void 0 || keptRowTotal(nested) <= keptRowTotal(out))) return out;
17068
17133
  if (nested !== void 0) return nested;
17069
17134
  }
17070
17135
  return markedSlice(full, annotated);
17071
17136
  }
17072
- function textResult2(details) {
17137
+ function textResult2(details, responseSchemas = []) {
17138
+ const components = responseSchemas.length > 0 ? responseComponents() : {};
17139
+ const shown = responseSchemas.reduce((value, schema) => renderRatioUnits(schema, value, components), details);
17073
17140
  return {
17074
- content: [{ type: "text", text: truncateToolResult(details) }],
17141
+ content: [{ type: "text", text: truncateToolResult(shown) }],
17075
17142
  details
17076
17143
  };
17077
17144
  }
@@ -17097,10 +17164,11 @@ function stripProjectFromJsonSchema(jsonSchema) {
17097
17164
  function mcpToAgentTool(tool, ctx) {
17098
17165
  const { schema: visibleSchema, hadProject } = stripProjectFromJsonSchema(tool.inputJsonSchema);
17099
17166
  const parameters = Type2.Unsafe(visibleSchema);
17167
+ const responseSchemas = responseSchemasFor(tool.openApiOperations);
17100
17168
  const execute = async (_toolCallId, params) => {
17101
17169
  const handlerInput = hadProject ? { ...params, project: ctx.projectName } : params;
17102
17170
  const result2 = await runWithUsageTags(ctx.client, { mcpTool: tool.name, mcpCall: randomUUID() }, () => tool.handler(ctx.client, handlerInput));
17103
- return textResult2(result2);
17171
+ return textResult2(result2, responseSchemas);
17104
17172
  };
17105
17173
  return {
17106
17174
  name: tool.name,
@@ -17472,11 +17540,11 @@ function recordLlmUsageEvent(args) {
17472
17540
  var AERO_MEMORY_SEPARATOR = "\n\n---\n\n";
17473
17541
  var AERO_MEMORY_BLOCK_PREFIX = `${AERO_MEMORY_SEPARATOR}<memory>
17474
17542
  `;
17475
- function isRecord4(value) {
17543
+ function isRecord5(value) {
17476
17544
  return Boolean(value && typeof value === "object" && !Array.isArray(value));
17477
17545
  }
17478
17546
  function isTextSystemBlock(value) {
17479
- return isRecord4(value) && value.type === "text" && typeof value.text === "string";
17547
+ return isRecord5(value) && value.type === "text" && typeof value.text === "string";
17480
17548
  }
17481
17549
  function splitAeroHydratedSystemPrompt(systemPrompt) {
17482
17550
  const idx = systemPrompt.lastIndexOf(AERO_MEMORY_BLOCK_PREFIX);
@@ -17488,7 +17556,7 @@ function splitAeroHydratedSystemPrompt(systemPrompt) {
17488
17556
  }
17489
17557
  function splitAeroAnthropicSystemCachePayload(payload, model) {
17490
17558
  if (model.api !== "anthropic-messages") return void 0;
17491
- if (!isRecord4(payload) || !Array.isArray(payload.system)) return void 0;
17559
+ if (!isRecord5(payload) || !Array.isArray(payload.system)) return void 0;
17492
17560
  let changed = false;
17493
17561
  const nextSystem = [];
17494
17562
  for (const block of payload.system) {
@@ -19943,7 +20011,7 @@ var MAX_TEXT_LENGTH = 4e3;
19943
20011
  var MAX_BODY_BYTES = 512e3;
19944
20012
  var USER_AGENT2 = "Canonry/1.0 (site-analysis)";
19945
20013
  function fetchWithPinnedAddress(target) {
19946
- return new Promise((resolve) => {
20014
+ return new Promise((resolve2) => {
19947
20015
  const port = target.url.port ? Number(target.url.port) : 443;
19948
20016
  const path9 = target.url.pathname + target.url.search;
19949
20017
  const req = https2.request(
@@ -19967,17 +20035,17 @@ function fetchWithPinnedAddress(target) {
19967
20035
  if (res.statusCode >= 300 && res.statusCode < 400) {
19968
20036
  const location = res.headers.location ?? "";
19969
20037
  res.resume();
19970
- resolve(`REDIRECT:${location}`);
20038
+ resolve2(`REDIRECT:${location}`);
19971
20039
  return;
19972
20040
  }
19973
20041
  res.resume();
19974
- resolve("");
20042
+ resolve2("");
19975
20043
  return;
19976
20044
  }
19977
20045
  const contentType = res.headers["content-type"] ?? "";
19978
20046
  if (!contentType.includes("text/html")) {
19979
20047
  res.resume();
19980
- resolve("");
20048
+ resolve2("");
19981
20049
  return;
19982
20050
  }
19983
20051
  const chunks = [];
@@ -19988,12 +20056,12 @@ function fetchWithPinnedAddress(target) {
19988
20056
  chunks.push(chunk);
19989
20057
  }
19990
20058
  });
19991
- res.on("end", () => resolve(Buffer.concat(chunks).toString("utf-8")));
19992
- res.on("error", () => resolve(""));
20059
+ res.on("end", () => resolve2(Buffer.concat(chunks).toString("utf-8")));
20060
+ res.on("error", () => resolve2(""));
19993
20061
  }
19994
20062
  );
19995
20063
  req.on("timeout", () => req.destroy(new Error("timeout")));
19996
- req.on("error", () => resolve(""));
20064
+ req.on("error", () => resolve2(""));
19997
20065
  req.end();
19998
20066
  });
19999
20067
  }
@@ -23218,8 +23286,8 @@ async function createServer(opts) {
23218
23286
  checkLatestVersionForServer();
23219
23287
  let resolveRuntimeStartup;
23220
23288
  let rejectRuntimeStartup;
23221
- const runtimeStartup = new Promise((resolve, reject) => {
23222
- resolveRuntimeStartup = resolve;
23289
+ const runtimeStartup = new Promise((resolve2, reject) => {
23290
+ resolveRuntimeStartup = resolve2;
23223
23291
  rejectRuntimeStartup = reject;
23224
23292
  });
23225
23293
  void runtimeStartup.catch(() => {