@cyanheads/mcp-ts-core 0.13.13 → 0.13.14

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 (39) hide show
  1. package/AGENTS.md +4 -4
  2. package/CLAUDE.md +4 -4
  3. package/README.md +1 -1
  4. package/changelog/0.13.x/0.13.14.md +68 -0
  5. package/dist/core/app.d.ts +4 -3
  6. package/dist/core/app.d.ts.map +1 -1
  7. package/dist/core/app.js.map +1 -1
  8. package/dist/mcp-server/prompts/prompt-registration.d.ts.map +1 -1
  9. package/dist/mcp-server/prompts/prompt-registration.js +12 -5
  10. package/dist/mcp-server/prompts/prompt-registration.js.map +1 -1
  11. package/dist/mcp-server/prompts/utils/promptDefinition.d.ts +4 -1
  12. package/dist/mcp-server/prompts/utils/promptDefinition.d.ts.map +1 -1
  13. package/dist/mcp-server/prompts/utils/promptDefinition.js.map +1 -1
  14. package/dist/mcp-server/tools/utils/inputPrevalidation.d.ts +309 -26
  15. package/dist/mcp-server/tools/utils/inputPrevalidation.d.ts.map +1 -1
  16. package/dist/mcp-server/tools/utils/inputPrevalidation.js +870 -106
  17. package/dist/mcp-server/tools/utils/inputPrevalidation.js.map +1 -1
  18. package/dist/mcp-server/tools/utils/schemaShape.d.ts +127 -5
  19. package/dist/mcp-server/tools/utils/schemaShape.d.ts.map +1 -1
  20. package/dist/mcp-server/tools/utils/schemaShape.js +432 -4
  21. package/dist/mcp-server/tools/utils/schemaShape.js.map +1 -1
  22. package/dist/mcp-server/tools/utils/toolDefinition.d.ts +7 -3
  23. package/dist/mcp-server/tools/utils/toolDefinition.d.ts.map +1 -1
  24. package/dist/mcp-server/tools/utils/toolDefinition.js.map +1 -1
  25. package/dist/mcp-server/tools/utils/toolHandlerFactory.d.ts +47 -23
  26. package/dist/mcp-server/tools/utils/toolHandlerFactory.d.ts.map +1 -1
  27. package/dist/mcp-server/tools/utils/toolHandlerFactory.js +777 -236
  28. package/dist/mcp-server/tools/utils/toolHandlerFactory.js.map +1 -1
  29. package/dist/utils/telemetry/attributes.d.ts +3 -2
  30. package/dist/utils/telemetry/attributes.d.ts.map +1 -1
  31. package/dist/utils/telemetry/attributes.js +3 -2
  32. package/dist/utils/telemetry/attributes.js.map +1 -1
  33. package/framework-skills/add-tool/SKILL.md +15 -7
  34. package/framework-skills/api-errors/SKILL.md +8 -8
  35. package/framework-skills/api-telemetry/SKILL.md +4 -4
  36. package/framework-skills/api-testing/SKILL.md +2 -2
  37. package/framework-skills/design-mcp-server/SKILL.md +3 -2
  38. package/framework-skills/field-test/SKILL.md +3 -2
  39. package/package.json +3 -3
@@ -14,9 +14,17 @@
14
14
  * in another case style (`max_results` for `maxResults`). Rewritten to the
15
15
  * canonical key before parsing. A one-to-one mapping fixed ahead of time, not
16
16
  * the nearest-key guess #232 rejected.
17
- * 3. **Representation repair (#234, #479, #487)** — a JSON-stringified array or
18
- * object where one was declared, or an integer where a string was. Applied
19
- * only *after* the parse has already failed, and kept only when it flips the
17
+ * 3. **Representation repair (#234, #479, #487, #707, #602, #616, #570, #599,
18
+ * #714)** — a JSON-stringified array or object where one was declared, an
19
+ * integer where a string was, a string spelling a number or boolean where
20
+ * only those are accepted, a lone string where an array was, or `null` for
21
+ * an optional field, which is deleted — at any path the rejection renders,
22
+ * inside the one union branch that survives selection included, at a
23
+ * discriminator or literal tag no variant accepts, and inside what a
24
+ * `z.preprocess()` made of the argument — tried first written in place at
25
+ * the issue path, then written into the output, which takes the argument's
26
+ * place only if the preprocess returns it unchanged. Applied only
27
+ * *after* the parse has already failed, and kept only when it flips the
20
28
  * arguments from invalid to valid: the author's schema is the sole arbiter,
21
29
  * so a repair can never touch input that was already valid.
22
30
  *
@@ -39,9 +47,18 @@
39
47
  * debug log and one counter increment instead — for the attempt whose
40
48
  * arguments the handler receives, never one the parse discarded. A call they
41
49
  * cannot rescue is rejected with the rewrites and underscore-rule drops of the
42
- * attempt whose rejection it carries reported (#468), since without them the caller cannot
43
- * tell a bad value from a key that was moved or discarded; a repair the
44
- * re-parse discarded leaves no trace there.
50
+ * attempt whose rejection it carries reported (#468), since without them the
51
+ * caller cannot tell a bad value from a key that was moved or discarded, and
52
+ * with each alias sent beside its target named as one in the hint (#639),
53
+ * since an unknown or dropped key would send the caller looking for a typo. Its
54
+ * issues come from a parse with only the repairs that held applied (#706), so
55
+ * a value the schema accepted once repaired is not reported and one it refused
56
+ * is reported as sent — unless that parse validates, which only a union or a
57
+ * cross-field refinement allows, and the first parse is reported instead; the
58
+ * rejection itself never mentions a repair. A value that held only written in
59
+ * place below a transform that reorders or rewrites it is reported as sent
60
+ * too: the issues name positions in the transform's output, where a repair
61
+ * written in place is not.
45
62
  *
46
63
  * The split between log and counter is deliberate. Counter attributes are
47
64
  * bounded and author- or framework-defined — the ignore-list entry that
@@ -50,14 +67,15 @@
50
67
  * a client invents (#114). The raw key and alias go to the debug log, which is
51
68
  * where an operator looks when a counter shows a new client artifact and where
52
69
  * cardinality costs nothing, at most their first 1,024 characters bounding its size
53
- * (#631) — and, on a rejection, back to the caller who sent them, whole, since
54
- * an error payload is per call rather than a permanent series.
70
+ * (#631) — and, on a rejection, back to the caller who sent them, cut the same
71
+ * way (#648), since an error payload is per call rather than a permanent series.
55
72
  *
56
73
  * @module src/mcp-server/tools/utils/inputPrevalidation
57
74
  */
58
75
  import type { ZodError } from 'zod';
59
76
  import { type RequestContext } from '../../../utils/internal/requestContext.js';
60
- import type { AnyToolDefinition } from './toolDefinition.js';
77
+ import { type TransformCache, type TransformSite } from './schemaShape.js';
78
+ import type { AnyToolDefinition, ToolInputSchema } from './toolDefinition.js';
61
79
  /**
62
80
  * Server-level switches for the pre-validation step, set once via
63
81
  * `createApp({ input })`. Every stage is on with no configuration; an entry
@@ -74,10 +92,14 @@ export interface InputHandlingOptions {
74
92
  caseStyleAliases?: boolean;
75
93
  /**
76
94
  * Retry a failed parse once against repaired argument *values* — a
77
- * JSON-stringified array or object parsed back into what it encodes, or a
78
- * safe integer sent where a string was expected turned into its decimal
79
- * string. `false` turns the repair off, so each order of the key stages is
80
- * parsed once, with the values as sent. Default `true`.
95
+ * JSON-stringified array or object parsed back into what it encodes, a safe
96
+ * integer sent where a string was expected turned into its decimal string, a
97
+ * string sent where only numbers or booleans are accepted turned into the
98
+ * one it spells (`"15"`, `"true"`), a lone string sent where an array was
99
+ * expected wrapped as its only element, and `null` sent for an optional
100
+ * field deleted so the field reads as unset. `false` turns the repair off,
101
+ * so each order of the key stages is parsed once, with the values as sent.
102
+ * Default `true`.
81
103
  */
82
104
  coerce?: boolean;
83
105
  /**
@@ -97,6 +119,10 @@ declare const COERCION_KINDS: {
97
119
  readonly stringified_array: 'a stringified array';
98
120
  readonly stringified_object: 'a stringified object';
99
121
  readonly integer_as_string: 'an integer sent for a string';
122
+ readonly string_as_number: 'a string sent for a number';
123
+ readonly string_as_boolean: 'a string sent for a boolean';
124
+ readonly string_as_array: 'a string sent for an array';
125
+ readonly null_as_absent: 'null sent for an optional field';
100
126
  };
101
127
  /** One repair {@link repairRepresentations} can perform. */
102
128
  export type CoercionKind = keyof typeof COERCION_KINDS;
@@ -104,12 +130,29 @@ export type CoercionKind = keyof typeof COERCION_KINDS;
104
130
  type AliasKind = 'case_style' | 'declared';
105
131
  /** One Zod issue from a failed parse of the arguments. */
106
132
  type ArgumentIssue = ZodError['issues'][number];
133
+ /**
134
+ * A Zod issue and the full argument path it sits at. The path equals
135
+ * `issue.path` except for an issue lifted out of a union branch, whose
136
+ * branch-relative path follows the union's own (#492).
137
+ */
138
+ export interface LocatedIssue {
139
+ readonly issue: ArgumentIssue;
140
+ readonly path: readonly PropertyKey[];
141
+ /**
142
+ * The one-literal issues other branches of an enclosing union raised at
143
+ * this same path — branches the rendering dropped for failing on one
144
+ * literal alone (#417). The repair reads the value as a plain union field
145
+ * holding those branches would, so a dropped `z.literal(5)` branch keeps `6`
146
+ * from becoming `"6"` (#570).
147
+ */
148
+ readonly rivals?: readonly ArgumentIssue[];
149
+ }
107
150
  /**
108
151
  * What the pre-parse stages changed that the caller wrote, reported on an
109
152
  * argument rejection (#468) so a caller can tell a bad value from a key that
110
153
  * was moved or discarded. Keys only, never values.
111
154
  */
112
- export interface PrevalidationReport {
155
+ interface PrevalidationReport {
113
156
  /** Root keys rewritten to their canonical spelling, in argument order. */
114
157
  readonly aliased: ReadonlyArray<{
115
158
  readonly alias: string;
@@ -137,6 +180,24 @@ export type PrevalidationChange = {
137
180
  readonly kind: 'dropped';
138
181
  readonly rule: string;
139
182
  };
183
+ /**
184
+ * A declared key the caller sent together with an alias of it (#639). The
185
+ * alias stage leaves an alias in place when its target is already present, so
186
+ * the strict root rejects it as an unknown key, or the drop discards it as an
187
+ * undeclared underscore key — and naming it that way would send the caller
188
+ * looking for a typo when the problem is that two names for one field arrived.
189
+ */
190
+ export interface AliasCollision {
191
+ /** The aliases left in place because `target` was already present, in argument order. */
192
+ readonly declined: readonly string[];
193
+ /**
194
+ * Every key the caller sent for `target`, in argument order: the key itself,
195
+ * the aliases rewritten to it, and the declined ones.
196
+ */
197
+ readonly keys: readonly string[];
198
+ /** The declared key. */
199
+ readonly target: string;
200
+ }
140
201
  /** One ordering of the pre-parse stages — what {@link prevalidateToolArguments} hands the parse. */
141
202
  export interface PrevalidatedArguments {
142
203
  /** The arguments to parse — the caller's own object when nothing applied. */
@@ -147,22 +208,84 @@ export interface PrevalidatedArguments {
147
208
  * receives, and {@link recordPrevalidation} emits that one.
148
209
  */
149
210
  readonly changes: readonly PrevalidationChange[];
211
+ /**
212
+ * The aliases the alias stage declined because their target was already
213
+ * present, grouped by target, or `undefined` when it declined none. Worked
214
+ * out only when called: a rejection's hint is the one reader, so a call that
215
+ * validates never pays for it. Kept off `report`, which records what the
216
+ * stages changed: a rejection's hint names these keys, and `data.input` never
217
+ * does.
218
+ */
219
+ readonly collisions?: () => readonly AliasCollision[] | undefined;
150
220
  /** Present only when a rewrite or an underscore-rule drop happened. */
151
221
  readonly report?: PrevalidationReport;
152
222
  }
223
+ /**
224
+ * One value {@link repairRepresentations} repaired: where it sits, what the
225
+ * caller sent there, and what replaces it — or, for `null_as_absent`, that the
226
+ * key is deleted. {@link applyRepairs} writes any set of them onto the caller's
227
+ * arguments, so a parse can be retried with only some of a call's repairs
228
+ * applied, and leaving a deletion out of the set keeps the caller's `null`.
229
+ *
230
+ * A value below a `z.preprocess()` or a `.transform().pipe()` sits in what the
231
+ * transform made of the argument, not in the argument itself (#599): `within`
232
+ * names each such transform, outermost first, and the repair is written into
233
+ * its output.
234
+ */
235
+ export type Repair = ({
236
+ readonly kind: Exclude<CoercionKind, 'null_as_absent'>;
237
+ /** The full argument path the value sits at. */
238
+ readonly path: readonly PropertyKey[];
239
+ /** The value at `path` — the caller's own, or a transform's output there. */
240
+ readonly sent: unknown;
241
+ /** The value that replaces it. */
242
+ readonly value: unknown;
243
+ } | {
244
+ readonly kind: 'null_as_absent';
245
+ /** The full argument path of the key that is deleted. */
246
+ readonly path: readonly PropertyKey[];
247
+ readonly sent: null;
248
+ }) & {
249
+ /** The transforms above `path`, outermost first; absent when there are none. */
250
+ readonly within?: readonly TransformSite[];
251
+ };
153
252
  /** What {@link repairRepresentations} produced. */
154
253
  export interface RepairedArguments {
155
254
  /** The repaired arguments — the input itself when nothing was repairable. */
156
255
  readonly args: unknown;
256
+ /**
257
+ * The arguments with each repair below a transform written in place instead
258
+ * — at its issue path in the arguments as sent, never into the transform's
259
+ * output — and the kinds they carry. Present only when such a repair was
260
+ * found; {@link parseToolArguments} parses it after {@link repairAsSent}'s
261
+ * repair and before `args`.
262
+ */
263
+ readonly inPlace?: {
264
+ readonly args: unknown;
265
+ readonly kinds: readonly CoercionKind[];
266
+ };
157
267
  /** Each kind that fired at least once, in {@link COERCION_KINDS} order. */
158
268
  readonly kinds: readonly CoercionKind[];
269
+ /** Every repair {@link RepairedArguments.args} carries, one per path, in issue order. */
270
+ readonly repairs: readonly Repair[];
271
+ /**
272
+ * The arguments without the original repairs `args` adds beside the
273
+ * rendered issues' own, and the kinds they carry. Present only when an
274
+ * original repair was added and these still differ from the input;
275
+ * {@link parseToolArguments} parses them when `args` fails.
276
+ */
277
+ readonly unaided?: {
278
+ readonly args: unknown;
279
+ readonly kinds: readonly CoercionKind[];
280
+ };
159
281
  }
160
282
  /**
161
283
  * Emits one counter increment and one debug log per change an attempt made, in
162
284
  * the order its stages made them. {@link parseToolArguments} calls it once per
163
285
  * call, for the attempt whose arguments the handler receives — or, on a
164
- * rejection, the first attempt, the one the rejection reports — so a key the
165
- * alias-first retry rewrote never also counts as dropped (#563).
286
+ * rejection, the attempt the rejection reports, which is the alias-first
287
+ * retry's when it ran — so a key the alias-first retry rewrote never also
288
+ * counts as dropped (#563).
166
289
  *
167
290
  * The key a record names is the caller's, of whatever length the caller wrote,
168
291
  * so the message and the field carry at most its first 1,024 characters, with
@@ -209,23 +332,62 @@ export declare function prevalidateAliasFirst(def: AnyToolDefinition, args: unkn
209
332
  /**
210
333
  * Undoes a representation slip at each path the failed parse's issues named:
211
334
  * a string whose trimmed form is a JSON array or object is parsed back into
212
- * what it encodes (#234, #479), and a safe integer where a string was expected
213
- * becomes its decimal string (#487). Keys are never added, dropped, or renamed,
214
- * and a value no issue points at is returned untouched.
335
+ * what it encodes (#234, #479), a safe integer where a string was expected
336
+ * becomes its decimal string (#487), a string where only numbers or booleans
337
+ * are accepted becomes the one it spells (#707), a lone string where an array
338
+ * was expected becomes its only element (#602), and `null` at a key the
339
+ * enclosing `z.object()` of `input` declares optional is deleted (#616). That
340
+ * deletion is the only key change: no key is added or renamed, none is dropped
341
+ * but a `null`-valued one, and a value no issue points at is returned
342
+ * untouched.
343
+ *
344
+ * **`null` means unset only where the schema says so.** The key must be one
345
+ * the enclosing object declares — resolved by {@link objectSchemaAt}, through
346
+ * wrappers and into the variant a discriminator selects — and its field must
347
+ * refuse `null` and accept `undefined`. A required field's `null` keeps its
348
+ * rejection, a `.nullable()` field never raises the issue, and a `z.record()`
349
+ * entry, a key under an author-opened catchall, and an array element are data
350
+ * whose key set is the meaning, so none is deleted. The value, not the issue
351
+ * code, is the trigger: `null` on an optional enum fails as `invalid_value`,
352
+ * whose message never says `null`.
215
353
  *
216
354
  * **Targeted, not a full walk.** A rejection names exactly the values the schema
217
355
  * could not accept, and repairing anything else loses repairs that should have
218
356
  * succeeded: one call carrying a stringified array for an array field *and* a
219
357
  * free-text field legitimately holding `"[1,2]"` would have both rewritten, the
220
358
  * re-parse would fail on the free-text field, and the whole call would be
221
- * rejected over a value that was valid all along. An `invalid_union` issue's
222
- * outer path counts like any other — that is the value the union rejected, and
223
- * the only one read: a number inside one branch of a union field stays as sent.
359
+ * rejected over a value that was valid all along.
360
+ *
361
+ * **The issues the rejection renders.** {@link parseToolArguments} passes the
362
+ * list the rejection's message renders, each at its full path: a union whose
363
+ * selection leaves one branch failing below its root contributes that branch's
364
+ * issues under the union's path, recursively (#570), and every other union
365
+ * keeps its one issue at its own path — the value the union rejected, read as
366
+ * a whole — and is also read at each path below it where every branch listed
367
+ * the values it takes (#714, {@link everyBranchRefuses}). That is where a
368
+ * literal tag no branch takes sits, read as a plain field holding every
369
+ * branch's literal reads it: `"1"` against tags `1` and `2` reads as it does
370
+ * against `z.union([z.literal(1), z.literal(2)])`. A discriminated union's
371
+ * unmatched discriminator, which Zod reports with no branches, is read from
372
+ * the tags it lists the same way ({@link unmatchedDiscriminator}). Inside the
373
+ * lifted branch each kind repairs exactly as it would in a non-union field,
374
+ * with its own gate. Only one branch looks inside the value there: every other
375
+ * failed at its root or on one literal, and so rejects the value whatever it
376
+ * holds — except where that literal sits at the very path being repaired,
377
+ * which the entry carries as a rival, and the gate then reads the value as a
378
+ * plain union field of those branches (`6` beside a `z.literal(5)` branch
379
+ * stays a number, so it stays rejected). A branch that accepts a number at the
380
+ * path is reported by Zod as its own check (`too_big`), which no gate takes.
381
+ * Two branches failing below their roots are never lifted, so neither is read
382
+ * below its root but where each lists the values it takes.
224
383
  *
225
384
  * **One pass, no stacking.** Only a value the first parse rejected is repaired,
226
- * and at most once, so a value one repair produced is never repaired again — an
227
- * integer inside a stringified array, a stringified field inside a stringified
228
- * object. The caller re-parses once.
385
+ * and at most once — the first issue at a path that yields a repair claims it —
386
+ * so a value one repair produced is never repaired again: an integer inside a
387
+ * stringified array, a stringified field inside a stringified object. The
388
+ * caller re-parses once. A repaired discriminator selects a variant Zod never
389
+ * parsed, so a second slip inside that variant is not repaired with it: the
390
+ * rejection reports it, the tag's repair held (#706).
229
391
  *
230
392
  * `JSON.parse` is the exact inverse of the `JSON.stringify` that produced a
231
393
  * string, and `String(n)` of a safe integer is the digits the caller sent, so
@@ -235,9 +397,130 @@ export declare function prevalidateAliasFirst(def: AnyToolDefinition, args: unkn
235
397
  * after validation has already failed and keeps the result only when it then
236
398
  * passes.
237
399
  *
400
+ * **A string is read as another type only where the field types it itself.**
401
+ * A field routed through a `.transform()`, `.pipe()`, or `z.preprocess()`
402
+ * can reject its transform's output rather than the string sent — `"15"` an
403
+ * ID-or-name lookup does not know — so a string there is never turned into a
404
+ * number, boolean, or one-element list. Nor is one at a path that could land on
405
+ * such a field ({@link routesThroughPipeAt}): one option of a plain union
406
+ * declaring it while another declares or catches the same key, one side of an
407
+ * intersection, or an option whose own tag the caller sent wrong — the tag
408
+ * itself included, so `"1"` stays a string where one branch types its tag
409
+ * through a `z.preprocess()`.
410
+ *
411
+ * **A value inside a transform's output (#599).** Below a `z.preprocess()` or
412
+ * a `.transform().pipe()`, an issue path runs through what the transform made
413
+ * of the argument — `items.0.year` inside the list a preprocess wrapped a lone
414
+ * object in — so each path is read through {@link argumentAt}, which re-applies
415
+ * the transform in-process. The repair is written into that output, and the
416
+ * output is put in the argument's place only when the transform, applied to
417
+ * it, returns it structurally unchanged ({@link applyRepairs}); a transform
418
+ * that would reorder it, rewrite a value in it, or reject it leaves the
419
+ * argument as sent. The field the value sits in still decides the string
420
+ * kinds: a plain `z.string()` inside a wrapped list takes them, a field that
421
+ * is itself a pipe does not.
422
+ *
423
+ * **The same values written in place, tried first.** A repair can also be read
424
+ * and written at its issue path in the arguments as sent, leaving the re-parse
425
+ * to run the transform over it again. That validates calls the substitution
426
+ * refuses — `[1, 2]` under a preprocess that reverses a list reaches the
427
+ * handler as `["2", "1"]` — and gives some a different value: `[5]` under one
428
+ * that doubles numbers reaches it as `["5"]`, where the substitution would
429
+ * hand on `["10"]`. The original repair ({@link repairAsSent}) already places
430
+ * every value Zod's own issues name that way, so each call it validated keeps
431
+ * its value; `inPlace` carries the placement where that repair does not reach
432
+ * — inside a union's one surviving branch, and beside this pass's other
433
+ * repairs — so such a call gets the value the field gets on its own. It is
434
+ * built whenever a value below a transform, or behind one that throws when
435
+ * re-applied, is repairable that way, with the kinds that placement carries: a
436
+ * stringified array or object, and an integer sent for a string.
437
+ * {@link parseToolArguments} parses it after the original repair and before
438
+ * `args`, and keeps it when it validates. Each repair of `original` that no
439
+ * rendered issue reaches and that sits at no transform — a union field's
440
+ * value read whole, a stringified list beside a branch that splits a string —
441
+ * joins `repairs` too ({@link withOriginal}), so a call needing it beside a
442
+ * repair only this pass makes validates, and a rejection reports it as held.
443
+ * The repairs without it come back as `unaided`, parsed when `args` fails:
444
+ * integers inside the list a branch decodes from JSON text need the lifted
445
+ * branch's repairs, and the original reading of the text refuses them.
446
+ *
447
+ * Every value is read beside the caller's arguments, each transform at most
448
+ * once per value through `transforms`, and the repairs found are written in
449
+ * one {@link applyRepairs} pass per placement, so the work is linear in the
450
+ * issues however many values one array holds. They come back as `repairs`,
451
+ * one per path.
452
+ *
238
453
  * `args` is the argument itself when nothing was repairable, which is the
239
454
  * signal the caller uses to skip the second parse.
240
455
  */
241
- export declare function repairRepresentations(args: unknown, issues: readonly ArgumentIssue[]): RepairedArguments;
456
+ export declare function repairRepresentations(args: unknown, issues: readonly LocatedIssue[], input: ToolInputSchema, transforms: TransformCache, original?: readonly Repair[]): RepairedArguments;
457
+ /**
458
+ * The repair 0.13.13 and earlier made, which every call it validated must
459
+ * still get first: each of the failed parse's own issues at a non-root path,
460
+ * read and written at that path in the arguments as sent
461
+ * ({@link inPlaceRepair}). A value takes one kind of those repairs whichever
462
+ * issue names it, and {@link applyRepairs} writes a path two repairs share
463
+ * once. Zod's own list, not the one the rejection renders: a union whose
464
+ * selection lifts a branch (#570) is read here as the one value it rejected,
465
+ * so a stringified list for a field whose other branch splits or wraps a
466
+ * string parses back into the list, as that reading gave it. `undefined` when
467
+ * nothing repairs.
468
+ */
469
+ export declare function repairAsSent(args: unknown, issues: readonly ArgumentIssue[]): {
470
+ readonly args: unknown;
471
+ readonly kinds: readonly CoercionKind[];
472
+ readonly repairs: readonly Repair[];
473
+ } | undefined;
474
+ /**
475
+ * Writes `repairs` onto `args`, copying each container on their paths once and
476
+ * leaving the caller's own objects untouched — so a thousand repaired elements
477
+ * of one array cost one copy of it, not a thousand. A `null_as_absent` repair
478
+ * leaves its key out of the copy of the object that holds it. A path two
479
+ * repairs share takes the first. Any subset of one call's
480
+ * {@link RepairedArguments.repairs} can be written, which is how
481
+ * {@link parseToolArguments} builds a rejection from the repairs that held.
482
+ *
483
+ * A repair inside a transform's output (#599) is written into that output, and
484
+ * the output takes the argument's place only when the transform, applied to
485
+ * it, returns it unchanged — compared structurally, since a transform may
486
+ * rebuild the list it was handed. That is the one check the validity re-parse
487
+ * cannot make: a transform that reorders or rewrites its input could validate
488
+ * with values the repair never wrote. Otherwise every repair inside that
489
+ * output is dropped and the argument is left as sent, so the call keeps its
490
+ * rejection. A transform that throws on the output counts as one that changed
491
+ * it. Nested transforms are checked at each position, innermost first.
492
+ *
493
+ * Object copies go through `Object.fromEntries`, which *defines* each property
494
+ * rather than assigning it. `copy[key] = value` would route a caller's own
495
+ * `__proto__` key — which `JSON.parse` creates as an ordinary own data property
496
+ * — through `Object.prototype`'s setter: the key would vanish and the copy's
497
+ * prototype would become whatever the caller sent, which Zod then reads
498
+ * inherited values from. Defining keeps the key and the prototype, so no key is
499
+ * added or renamed, and none is dropped but a deleted one.
500
+ */
501
+ export declare function applyRepairs(args: unknown, repairs: readonly Repair[]): unknown;
502
+ /**
503
+ * The repairs a failed re-parse kept (#706): each one no issue of `issues` lies
504
+ * at or below — the re-parse accepted the value it wrote, and whatever still
505
+ * fails is somewhere else. A union's issue counts at its own path and every
506
+ * branch's issues at theirs, whichever branch the rendering would select: a
507
+ * repair one branch accepts and another refuses at the same path did not hold,
508
+ * because the repaired value is what the refusing branch would then report.
509
+ *
510
+ * Each issue walks the tree of repair paths along its own path, so the check
511
+ * is linear in the issues and the repairs together, however many of each one
512
+ * array carries. An issue is walked from a node once (#648): Zod hands every
513
+ * branch that parsed the same value the same issue objects, so a recursive
514
+ * union whose `and` and `or` branches share a clause lists it under both, and
515
+ * walking each listing would double the walk per level of the caller's
516
+ * nesting.
517
+ */
518
+ export declare function heldRepairs(repairs: readonly Repair[], issues: readonly ArgumentIssue[]): readonly Repair[];
519
+ /**
520
+ * Structural equality over what arguments are made of: the same value, or
521
+ * arrays and plain objects holding equal entries under the same keys. Any
522
+ * other object equals only itself.
523
+ */
524
+ export declare function sameValue(a: unknown, b: unknown): boolean;
242
525
  export {};
243
526
  //# sourceMappingURL=inputPrevalidation.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"inputPrevalidation.d.ts","sourceRoot":"","sources":["../../../../src/mcp-server/tools/utils/inputPrevalidation.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"inputPrevalidation.d.ts","sourceRoot":"","sources":["../../../../src/mcp-server/tools/utils/inputPrevalidation.ts"],"names":[],"mappings":"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"}