source dump of claude code
at main 29 lines 1.2 kB view raw
1import { z } from 'zod/v4' 2 3/** 4 * Boolean that also accepts the string literals "true"/"false". 5 * 6 * Tool inputs arrive as model-generated JSON. The model occasionally quotes 7 * booleans — `"replace_all":"false"` instead of `"replace_all":false` — and 8 * z.boolean() rejects that with a type error. z.coerce.boolean() is the wrong 9 * fix: it uses JS truthiness, so "false" → true. 10 * 11 * z.preprocess emits {"type":"boolean"} to the API schema, so the model is 12 * still told this is a boolean — the string tolerance is invisible client-side 13 * coercion, not an advertised input shape. 14 * 15 * .optional()/.default() go INSIDE (on the inner schema), not chained after: 16 * chaining them onto ZodPipe widens z.output<> to unknown in Zod v4. 17 * 18 * semanticBoolean() → boolean 19 * semanticBoolean(z.boolean().optional()) → boolean | undefined 20 * semanticBoolean(z.boolean().default(false)) → boolean 21 */ 22export function semanticBoolean<T extends z.ZodType>( 23 inner: T = z.boolean() as unknown as T, 24) { 25 return z.preprocess( 26 (v: unknown) => (v === 'true' ? true : v === 'false' ? false : v), 27 inner, 28 ) 29}