@agimon-ai/foundation-validator 0.2.0 → 0.3.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.
- package/dist/index.cjs +3 -3
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +0 -1
- package/dist/index.d.cts.map +1 -1
- package/dist/index.d.mts +0 -1
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs.map +1 -1
- package/package.json +7 -8
package/dist/index.cjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
let e=require(`zod`);function t(e){return e._def.type??``}function n(e){let r=t(e);if(r===`optional`||r===`nullable`||r===`default`){let t=e._def.innerType;return t?n(t):e}return e}function r(e){let i=n(e),a=t(i);return a===`object`||a===`array`||a===`record`?!0:a===`union`?(i._def.options??[]).some(r):!1}function i(e,t){let n={...e};for(let[e,i]of Object.entries(t.shape)){let t=n[e];if(typeof t==`string`&&r(i))try{n[e]=JSON.parse(t)}catch{}}return n}function a(e){return e._def.type??``}function o(e){return e._def.innerType}function s(e){let t=a(e);return t!==`optional`&&t!==`default`}function c(e){switch(a(e)){case`string`:return`string`;case`number`:return`number`;case`boolean`:return`boolean`;case`bigint`:return`bigint`;case`null`:return`null`;case`undefined`:return`undefined`;case`any`:return`any`;case`unknown`:return`unknown`;case`literal`:return JSON.stringify(e._def.value);case`enum`:return`enum [${(e.options??[]).join(`, `)}]`;case`array`:{let t=e._def.element;return t?`${c(t)}[]`:`unknown[]`}case`record`:{let t=e._def.valueType;return t?`Record<string, ${c(t)}>`:`Record<string, unknown>`}case`object`:return`object`;case`optional`:case`nullable`:case`default`:{let t=o(e);return t?c(t):`unknown`}case`union`:return(e._def.options??[]).map(c).join(` | `);default:return`unknown`}}function l(e){return e.match(/received (\w+)(?:\s|$)/)?.[1]}function u(e){switch(e.code){case`invalid_type`:{let t=e;return l(t.message)===`undefined`?`Required field is missing`:t.message}case`invalid_value`:return`Invalid value — must be one of: ${e.values.join(`, `)}`;case`too_small`:{let t=e;return`Value too small — minimum is ${String(t.minimum)}${t.inclusive?` (inclusive)`:` (exclusive)`}`}case`too_big`:{let t=e;return`Value too large — maximum is ${String(t.maximum)}${t.inclusive?` (inclusive)`:` (exclusive)`}`}case`unrecognized_keys`:return`Unrecognized keys: ${e.keys.join(`, `)}`;default:return e.message}}function d(e,t,n){let r=`--${t}`;switch(e.code){case`invalid_type`:{let t=e,i=l(t.message);return i===`undefined`?`Provide: ${r} <${n?c(n):`value`}>`:i===`string`&&(t.expected===`record`||t.expected===`array`||t.expected===`object`)?`Received a JSON string instead of ${t.expected}.\n → The coercion layer should handle this automatically.\n → CLI usage: ${r} '<json ${t.expected}>'`:void 0}case`invalid_value`:{let t=e.values[0];return`Use: ${r} ${String(t)}`}default:return}}function f(e,t){if(e.length!==0)return t.shape[e[0]]}function p(e,t){let{schemaName:n,schema:r}=t??{},i=new Map;for(let t of e.issues){let e=t.path.length>0?t.path.map(String).join(`.`):`(root)`,n=i.get(e)??[];n.push(t),i.set(e,n)}let a=[n?`Validation failed for "${n}":`:`Validation failed:`];for(let[e,t]of i){a.push(``);let n=r?f(e.split(`.`),r):void 0,i=n?s(n):t.some(e=>{if(e.code!==`invalid_type`)return!1;let t=e.message;return l(t)===`undefined`}),o=n?c(n):``,p=`(${i?`required`:`optional`})${o?` — ${o}`:``}`;a.push(` • ${e} ${p}`);for(let r of t){a.push(` ✗ ${u(r)}`);let t=d(r,e,n);t&&a.push(` → ${t}`)}}return a.join(`
|
|
2
|
-
`)}function m(e){return e._def.type??``}function h(e){return e._def.innerType}function g(e){let t=m(e);if(t===`optional`||t===`nullable`||t===`default`){let t=h(e);return t?g(t):e}return e}function _(e){let t=m(e);return t!==`optional`&&t!==`default`}function v(e){if(m(e)===`default`)return e._def.defaultValue}function y(e){return e.description??``}function b(e){let t=g(e);switch(m(t)){case`boolean`:return`boolean`;case`number`:return`number`;case`object`:case`record`:case`array`:return`json`;case`union`:return(t._def.options??[]).some(e=>{let t=m(g(e));return t===`object`||t===`array`||t===`record`})?`json`:`string`;default:return`string`}}function x(e){let t=g(e);if(m(t)===`enum`)return t.options}function S(e,t){if(t&&t.length>0)return`<${t.join(`|`)}>`;switch(e){case`boolean`:return``;case`number`:return`<number>`;case`json`:return`<json>`;default:return`<string>`}}function C(e,t){let n=b(t),r=x(t),i=v(t),a=y(t);return{flag:`--${e}`,type:n,required:_(t),description:a,default:i,choices:r,typeLabel:c(t)}}
|
|
3
|
-
`)}function
|
|
1
|
+
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});let e=require(`zod`);function t(e){return e._def.type??``}function n(e){let r=t(e);if(r===`optional`||r===`nullable`||r===`default`){let t=e._def.innerType;return t?n(t):e}return e}function r(e){let i=n(e),a=t(i);return a===`object`||a===`array`||a===`record`?!0:a===`union`?(i._def.options??[]).some(r):!1}function i(e,t){let n={...e};for(let[e,i]of Object.entries(t.shape)){let t=n[e];if(typeof t==`string`&&r(i))try{n[e]=JSON.parse(t)}catch{}}return n}function a(e){return e._def.type??``}function o(e){return e._def.innerType}function s(e){let t=a(e);return t!==`optional`&&t!==`default`}function c(e){switch(a(e)){case`string`:return`string`;case`number`:return`number`;case`boolean`:return`boolean`;case`bigint`:return`bigint`;case`null`:return`null`;case`undefined`:return`undefined`;case`any`:return`any`;case`unknown`:return`unknown`;case`literal`:return JSON.stringify(e._def.value);case`enum`:return`enum [${(e.options??[]).join(`, `)}]`;case`array`:{let t=e._def.element;return t?`${c(t)}[]`:`unknown[]`}case`record`:{let t=e._def.valueType;return t?`Record<string, ${c(t)}>`:`Record<string, unknown>`}case`object`:return`object`;case`optional`:case`nullable`:case`default`:{let t=o(e);return t?c(t):`unknown`}case`union`:return(e._def.options??[]).map(c).join(` | `);default:return`unknown`}}function l(e){return e.match(/received (\w+)(?:\s|$)/)?.[1]}function u(e){switch(e.code){case`invalid_type`:{let t=e;return l(t.message)===`undefined`?`Required field is missing`:t.message}case`invalid_value`:return`Invalid value — must be one of: ${e.values.join(`, `)}`;case`too_small`:{let t=e;return`Value too small — minimum is ${String(t.minimum)}${t.inclusive?` (inclusive)`:` (exclusive)`}`}case`too_big`:{let t=e;return`Value too large — maximum is ${String(t.maximum)}${t.inclusive?` (inclusive)`:` (exclusive)`}`}case`unrecognized_keys`:return`Unrecognized keys: ${e.keys.join(`, `)}`;default:return e.message}}function d(e,t,n){let r=`--${t}`;switch(e.code){case`invalid_type`:{let t=e,i=l(t.message);return i===`undefined`?`Provide: ${r} <${n?c(n):`value`}>`:i===`string`&&(t.expected===`record`||t.expected===`array`||t.expected===`object`)?`Received a JSON string instead of ${t.expected}.\n → The coercion layer should handle this automatically.\n → CLI usage: ${r} '<json ${t.expected}>'`:void 0}case`invalid_value`:{let t=e.values[0];return`Use: ${r} ${String(t)}`}default:return}}function f(e,t){if(e.length!==0)return t.shape[e[0]]}function p(e,t){let{schemaName:n,schema:r}=t??{},i=new Map;for(let t of e.issues){let e=t.path.length>0?t.path.map(String).join(`.`):`(root)`,n=i.get(e)??[];n.push(t),i.set(e,n)}let a=[n?`Validation failed for "${n}":`:`Validation failed:`];for(let[e,t]of i){a.push(``);let n=r?f(e.split(`.`),r):void 0,i=n?s(n):t.some(e=>{if(e.code!==`invalid_type`)return!1;let t=e.message;return l(t)===`undefined`}),o=n?c(n):``,p=`(${i?`required`:`optional`})${o?` — ${o}`:``}`;a.push(` • ${e} ${p}`);for(let r of t){a.push(` ✗ ${u(r)}`);let t=d(r,e,n);t&&a.push(` → ${t}`)}}return a.join(`
|
|
2
|
+
`)}function m(e){return e._def.type??``}function h(e){return e._def.innerType}function g(e){let t=m(e);if(t===`optional`||t===`nullable`||t===`default`){let t=h(e);return t?g(t):e}return e}function _(e){let t=m(e);return t!==`optional`&&t!==`default`}function v(e){if(m(e)===`default`)return e._def.defaultValue}function y(e){return e.description??``}function b(e){let t=g(e);switch(m(t)){case`boolean`:return`boolean`;case`number`:return`number`;case`object`:case`record`:case`array`:return`json`;case`union`:return(t._def.options??[]).some(e=>{let t=m(g(e));return t===`object`||t===`array`||t===`record`})?`json`:`string`;default:return`string`}}function x(e){let t=g(e);if(m(t)===`enum`)return t.options}function S(e,t){if(t&&t.length>0)return`<${t.join(`|`)}>`;switch(e){case`boolean`:return``;case`number`:return`<number>`;case`json`:return`<json>`;default:return`<string>`}}function C(e,t){let n=b(t),r=x(t),i=v(t),a=y(t);return{flag:`--${e}`,type:n,required:_(t),description:a,default:i,choices:r,typeLabel:c(t)}}function w(e,t){return e.length>=t?`${e} `:e.padEnd(t)}function T(e){let t=S(e.type,e.choices),n=t?`${e.flag} ${t}`:e.flag,r=e.type===`json`?` — ${e.typeLabel}`:``,i=e.default===void 0?``:` [default: ${JSON.stringify(e.default)}]`,a=`${e.description}${r}${i}`.trim();return` ${w(n,36)}${a}`}function E(e,t){let n=[],r=t.command??`<tool>`;n.push(`Usage: ${r} [options]`),t.description&&(n.push(``),n.push(t.description));let i=e.filter(e=>e.required),a=e.filter(e=>!e.required);if(i.length>0){n.push(``),n.push(`Required:`);for(let e of i)n.push(T(e))}if(a.length>0){n.push(``),n.push(`Optional:`);for(let e of a)n.push(T(e))}return n.join(`
|
|
3
|
+
`)}function D(e,t){let n=Object.entries(e.shape).map(([e,t])=>C(e,t));return{args:n,help:E(n,t??{})}}function O(e){return(e.startsWith(`--`)?e.slice(2):e).replace(/-([a-z])/gi,(e,t)=>t.toUpperCase())}function k(e,t){let{args:n}=D(t),r=new Map(n.map(e=>[O(e.flag),e])),i=new Map(n.map(e=>[e.flag,e])),a={},o=0;for(;o<e.length;){let t=e[o];if(!t.startsWith(`--`)){o++;continue}if(t.startsWith(`--no-`)){let e=O(t.slice(5));a[e]=!1,o++;continue}let n=t.indexOf(`=`),s,c;n===-1?(s=t,c=void 0):(s=t.slice(0,n),c=t.slice(n+1));let l=O(s),u=r.get(l)??i.get(s);if(u?.type===`boolean`){a[l]=!0,o++;continue}let d;if(c!==void 0)d=c,o++;else if(o+1<e.length&&!e[o+1].startsWith(`--`))d=e[o+1],o+=2;else{a[l]=!0,o++;continue}if(u?.type===`json`)try{a[l]=JSON.parse(d)}catch{a[l]=d}else if(u?.type===`number`){let e=Number.parseFloat(d);a[l]=Number.isNaN(e)?d:e}else a[l]=d}return a}function A(t){if(!t||typeof t!=`object`||Array.isArray(t))return e.z.unknown();let n=t,r=n.anyOf??n.oneOf;if(Array.isArray(r)&&r.length>0){let t=r.map(A);return t.length===1?t[0]:e.z.union([t[0],t[1],...t.slice(2)])}if(Array.isArray(n.enum)&&n.enum.every(e=>typeof e==`string`)){let[t,r,...i]=n.enum;return t===void 0?e.z.unknown():r===void 0?e.z.literal(t):e.z.enum([t,r,...i])}let i=n.type;if(Array.isArray(i)){let t=i.filter(e=>e!==`null`),r=i.includes(`null`);if(t.length===0)return r?e.z.null():e.z.unknown();let a=t.length===1?A({...n,type:t[0]}):e.z.union(t.map(e=>A({...n,type:e})));return r?e.z.union([a,e.z.null()]):a}if(i===`string`)return e.z.string();if(i===`number`||i===`integer`)return e.z.number();if(i===`boolean`)return e.z.boolean();if(i===`null`)return e.z.null();if(i===`array`){let t=n.items?A(n.items):e.z.unknown();return e.z.array(t)}return i===`object`?n.properties&&typeof n.properties==`object`&&!Array.isArray(n.properties)?j(n):e.z.record(e.z.string(),e.z.unknown()):e.z.unknown()}function j(t){let n=t.properties,r=new Set(Array.isArray(t.required)?t.required:[]);if(!n)return e.z.object({});let i={};for(let[e,t]of Object.entries(n)){let n=A(t);i[e]=r.has(e)?n:n.optional()}return e.z.object(i)}exports.cliArgsToObject=k,exports.coerceArgs=i,exports.describeType=c,exports.formatZodError=p,exports.jsonSchemaToZod=j,exports.zodToCliArgs=D;
|
|
4
4
|
//# sourceMappingURL=index.cjs.map
|
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.cjs","names":["defType","defType","defInnerType","isRequired","lines: string[]","lines: string[]","result: Record<string, unknown>","key","flagToken: string","inlineValue: string | undefined","rawValue: string | undefined","z","shape: Record<string, z.ZodTypeAny>"],"sources":["../src/utils/coerceArgs.ts","../src/utils/formatZodError.ts","../src/utils/zodToCliArgs.ts","../src/utils/cliArgsToObject.ts","../src/utils/jsonSchemaToZod.ts"],"sourcesContent":["import { z } from 'zod';\n\n// ---------------------------------------------------------------------------\n// Internal helpers — Zod v4 compatible\n// ---------------------------------------------------------------------------\n\n// Zod v4 schema shapes expose $ZodType internally; use a structural interface\n// to avoid the public ZodType vs $ZodType mismatch.\ninterface ZodLike {\n _def: { type?: string; innerType?: ZodLike; options?: ZodLike[] };\n}\n\nfunction defType(schema: ZodLike): string {\n return schema._def.type ?? '';\n}\n\nfunction unwrapZodLike(schema: ZodLike): ZodLike {\n const t = defType(schema);\n if (t === 'optional' || t === 'nullable' || t === 'default') {\n const inner = schema._def.innerType;\n return inner ? unwrapZodLike(inner) : schema;\n }\n return schema;\n}\n\nfunction isNonPrimitive(schema: ZodLike): boolean {\n const core = unwrapZodLike(schema);\n const t = defType(core);\n if (t === 'object' || t === 'array' || t === 'record') return true;\n if (t === 'union') {\n return (core._def.options ?? []).some(isNonPrimitive);\n }\n return false;\n}\n\n// ---------------------------------------------------------------------------\n// Public API\n// ---------------------------------------------------------------------------\n\n/**\n * Walks a ZodObject's shape and, for any field that expects a non-primitive\n * type (object, array, record, or union containing one), attempts to\n * JSON.parse string values. Leaves the value unchanged if:\n * - it is not a string\n * - the schema expects a primitive\n * - the string is not valid JSON\n *\n * This handles the common Claude Code behaviour of stringifying nested args\n * (e.g. env: '{\"KEY\":\"val\"}' instead of env: { KEY: 'val' }).\n */\nexport function coerceArgs(args: Record<string, unknown>, schema: z.ZodObject<z.ZodRawShape>): Record<string, unknown> {\n const result = { ...args };\n\n for (const [key, rawSchema] of Object.entries(schema.shape)) {\n const value = result[key];\n if (typeof value !== 'string') continue;\n if (!isNonPrimitive(rawSchema as unknown as ZodLike)) continue;\n\n try {\n result[key] = JSON.parse(value);\n } catch {\n // keep as string — not valid JSON\n }\n }\n\n return result;\n}\n","import { z } from 'zod';\n\n// ---------------------------------------------------------------------------\n// Internal schema introspection — Zod v4 compatible\n// ---------------------------------------------------------------------------\n\n// Structural interface compatible with both $ZodType (internal) and ZodType (public)\ninterface ZodLike {\n _def: {\n type?: string;\n innerType?: ZodLike;\n element?: ZodLike;\n valueType?: ZodLike;\n options?: readonly ZodLike[];\n value?: unknown;\n };\n description?: string;\n}\n\nfunction defType(schema: ZodLike): string {\n return schema._def.type ?? '';\n}\n\nfunction defInnerType(schema: ZodLike): ZodLike | undefined {\n return schema._def.innerType;\n}\n\nfunction isRequired(schema: ZodLike): boolean {\n const t = defType(schema);\n return t !== 'optional' && t !== 'default';\n}\n\n/**\n * Produces a concise human-readable type label for a Zod schema.\n * Examples: 'string', 'string[]', 'Record<string, string>', 'enum [a, b]'\n */\nexport function describeType(schema: ZodLike): string {\n const t = defType(schema);\n switch (t) {\n case 'string':\n return 'string';\n case 'number':\n return 'number';\n case 'boolean':\n return 'boolean';\n case 'bigint':\n return 'bigint';\n case 'null':\n return 'null';\n case 'undefined':\n return 'undefined';\n case 'any':\n return 'any';\n case 'unknown':\n return 'unknown';\n case 'literal':\n return JSON.stringify(schema._def.value);\n case 'enum': {\n // ZodEnum in v4 exposes .options as a getter\n const opts = (schema as unknown as { options: string[] }).options ?? [];\n return `enum [${opts.join(', ')}]`;\n }\n case 'array': {\n const el = schema._def.element;\n return el ? `${describeType(el)}[]` : 'unknown[]';\n }\n case 'record': {\n const valType = schema._def.valueType;\n return valType ? `Record<string, ${describeType(valType)}>` : 'Record<string, unknown>';\n }\n case 'object':\n return 'object';\n case 'optional':\n case 'nullable':\n case 'default': {\n const inner = defInnerType(schema);\n return inner ? describeType(inner) : 'unknown';\n }\n case 'union': {\n const opts = schema._def.options ?? [];\n return opts.map(describeType).join(' | ');\n }\n default:\n return 'unknown';\n }\n}\n\n// ---------------------------------------------------------------------------\n// Issue formatting — Zod v4 issue shapes\n// ---------------------------------------------------------------------------\n\n// Zod v4 uses 'invalid_value' (not 'invalid_enum_value') for enum violations.\n// Use string cast on issue.code to avoid ZodIssueCode constraint errors.\n\ninterface InvalidTypeIssueV4 {\n code: string;\n expected: string;\n message: string;\n path: (string | number)[];\n}\n\ninterface InvalidValueIssueV4 {\n code: string;\n values: (string | number)[];\n message: string;\n path: (string | number)[];\n}\n\ninterface TooSmallIssueV4 {\n code: string;\n minimum: number | bigint;\n inclusive: boolean;\n message: string;\n path: (string | number)[];\n}\n\ninterface TooBigIssueV4 {\n code: string;\n maximum: number | bigint;\n inclusive: boolean;\n message: string;\n path: (string | number)[];\n}\n\ninterface UnrecognizedKeysIssueV4 {\n code: string;\n keys: string[];\n message: string;\n path: (string | number)[];\n}\n\nfunction extractReceived(message: string): string | undefined {\n return message.match(/received (\\w+)(?:\\s|$)/)?.[1];\n}\n\nfunction formatIssueMessage(issue: z.ZodIssue): string {\n const code = issue.code as string;\n switch (code) {\n case 'invalid_type': {\n const i = issue as unknown as InvalidTypeIssueV4;\n const received = extractReceived(i.message);\n if (received === 'undefined') return 'Required field is missing';\n return i.message;\n }\n // Zod v4 uses 'invalid_value' for enum violations\n case 'invalid_value': {\n const i = issue as unknown as InvalidValueIssueV4;\n return `Invalid value — must be one of: ${i.values.join(', ')}`;\n }\n case 'too_small': {\n const i = issue as unknown as TooSmallIssueV4;\n return `Value too small — minimum is ${String(i.minimum)}${i.inclusive ? ' (inclusive)' : ' (exclusive)'}`;\n }\n case 'too_big': {\n const i = issue as unknown as TooBigIssueV4;\n return `Value too large — maximum is ${String(i.maximum)}${i.inclusive ? ' (inclusive)' : ' (exclusive)'}`;\n }\n case 'unrecognized_keys': {\n const i = issue as unknown as UnrecognizedKeysIssueV4;\n return `Unrecognized keys: ${i.keys.join(', ')}`;\n }\n default:\n return issue.message;\n }\n}\n\nfunction getActionableHint(issue: z.ZodIssue, fieldPath: string, fieldSchema: ZodLike | undefined): string | undefined {\n const flag = `--${fieldPath}`;\n const code = issue.code as string;\n\n switch (code) {\n case 'invalid_type': {\n const i = issue as unknown as InvalidTypeIssueV4;\n const received = extractReceived(i.message);\n\n if (received === 'undefined') {\n const typeLabel = fieldSchema ? describeType(fieldSchema) : 'value';\n return `Provide: ${flag} <${typeLabel}>`;\n }\n\n if (received === 'string' && (i.expected === 'record' || i.expected === 'array' || i.expected === 'object')) {\n return `Received a JSON string instead of ${i.expected}.\\n → The coercion layer should handle this automatically.\\n → CLI usage: ${flag} '<json ${i.expected}>'`;\n }\n\n return undefined;\n }\n\n case 'invalid_value': {\n const i = issue as unknown as InvalidValueIssueV4;\n const example = i.values[0];\n return `Use: ${flag} ${String(example)}`;\n }\n\n default:\n return undefined;\n }\n}\n\nfunction getFieldSchema(pathSegments: string[], schema: z.ZodObject<z.ZodRawShape>): ZodLike | undefined {\n if (pathSegments.length === 0) return undefined;\n return schema.shape[pathSegments[0]] as unknown as ZodLike | undefined;\n}\n\n// ---------------------------------------------------------------------------\n// Public API\n// ---------------------------------------------------------------------------\n\n/**\n * Converts a ZodError into a multi-line string optimized for AI agents.\n *\n * Each field with errors shows:\n * - field name, whether it is required/optional, and its expected type\n * - a concise description of what went wrong\n * - a concrete actionable hint (e.g. CLI flag usage)\n *\n * Detecting stringified objects: when the error says \"expected record/array,\n * received string\", it calls out the common Claude Code serialisation issue\n * and explains that the coercion layer should handle it automatically.\n *\n * @example\n * try {\n * schema.parse(args);\n * } catch (err) {\n * if (err instanceof z.ZodError) {\n * console.error(formatZodError(err, { schemaName: 'run_spec', schema }));\n * }\n * }\n */\nexport function formatZodError(\n error: z.ZodError,\n options?: { schemaName?: string; schema?: z.ZodObject<z.ZodRawShape> },\n): string {\n const { schemaName, schema } = options ?? {};\n\n // Group issues by dotted path\n const byPath = new Map<string, z.ZodIssue[]>();\n for (const issue of error.issues) {\n const path = issue.path.length > 0 ? issue.path.map(String).join('.') : '(root)';\n const existing = byPath.get(path) ?? [];\n existing.push(issue);\n byPath.set(path, existing);\n }\n\n const header = schemaName ? `Validation failed for \"${schemaName}\":` : 'Validation failed:';\n const lines: string[] = [header];\n\n for (const [path, issues] of byPath) {\n lines.push('');\n\n const fieldSchema = schema ? getFieldSchema(path.split('.'), schema) : undefined;\n const required = fieldSchema\n ? isRequired(fieldSchema)\n : issues.some((i) => {\n if ((i.code as string) !== 'invalid_type') return false;\n const msg = (i as unknown as { message: string }).message;\n return extractReceived(msg) === 'undefined';\n });\n\n const typeDesc = fieldSchema ? describeType(fieldSchema) : '';\n const meta = `(${required ? 'required' : 'optional'})${typeDesc ? ` — ${typeDesc}` : ''}`;\n\n lines.push(` • ${path} ${meta}`);\n\n for (const issue of issues) {\n lines.push(` ✗ ${formatIssueMessage(issue)}`);\n const hint = getActionableHint(issue, path, fieldSchema);\n if (hint) {\n lines.push(` → ${hint}`);\n }\n }\n }\n\n return lines.join('\\n');\n}\n","import { z } from 'zod';\nimport type { CliArgDefinition, CliArgType, CliArgsResult } from '../types/index.js';\nimport { describeType } from './formatZodError.js';\n\n// ---------------------------------------------------------------------------\n// Internal helpers — Zod v4 compatible\n// ---------------------------------------------------------------------------\n\n// Structural interface compatible with both $ZodType (internal) and ZodType (public)\ninterface ZodLike {\n _def: { type?: string; innerType?: ZodLike; defaultValue?: unknown; options?: readonly ZodLike[] };\n description?: string;\n}\n\nfunction defType(schema: ZodLike): string {\n return schema._def.type ?? '';\n}\n\nfunction defInnerType(schema: ZodLike): ZodLike | undefined {\n return schema._def.innerType;\n}\n\nfunction unwrapSchema(schema: ZodLike): ZodLike {\n const t = defType(schema);\n if (t === 'optional' || t === 'nullable' || t === 'default') {\n const inner = defInnerType(schema);\n return inner ? unwrapSchema(inner) : schema;\n }\n return schema;\n}\n\nfunction isRequired(schema: ZodLike): boolean {\n const t = defType(schema);\n return t !== 'optional' && t !== 'default';\n}\n\nfunction getDefault(schema: ZodLike): unknown {\n if (defType(schema) === 'default') {\n return schema._def.defaultValue;\n }\n return undefined;\n}\n\nfunction getDescription(schema: ZodLike): string {\n return schema.description ?? '';\n}\n\n/**\n * Maps a Zod schema field to a CliArgType used for help text and parsing.\n */\nfunction resolveCliType(schema: ZodLike): CliArgType {\n const core = unwrapSchema(schema);\n const t = defType(core);\n\n switch (t) {\n case 'boolean':\n return 'boolean';\n case 'number':\n return 'number';\n case 'object':\n case 'record':\n case 'array':\n return 'json';\n case 'union': {\n const opts: readonly ZodLike[] = core._def.options ?? [];\n const hasNonPrimitive = opts.some((o) => {\n const ot = defType(unwrapSchema(o));\n return ot === 'object' || ot === 'array' || ot === 'record';\n });\n return hasNonPrimitive ? 'json' : 'string';\n }\n default:\n return 'string';\n }\n}\n\n/**\n * Returns enum choices if the (unwrapped) schema is a ZodEnum.\n */\nfunction getChoices(schema: ZodLike): string[] | undefined {\n const core = unwrapSchema(schema);\n if (defType(core) === 'enum') {\n return (core as unknown as { options: string[] }).options;\n }\n return undefined;\n}\n\n/**\n * Builds the value placeholder shown in help text, e.g. '<string>', '<json>',\n * '<playwright|extension>'.\n */\nfunction buildValuePlaceholder(argType: CliArgType, choices?: string[]): string {\n if (choices && choices.length > 0) return `<${choices.join('|')}>`;\n switch (argType) {\n case 'boolean':\n return '';\n case 'number':\n return '<number>';\n case 'json':\n return '<json>';\n default:\n return '<string>';\n }\n}\n\n/**\n * Converts a single schema field to a CliArgDefinition.\n */\nfunction fieldToCliArg(key: string, schema: ZodLike): CliArgDefinition {\n const argType = resolveCliType(schema);\n const choices = getChoices(schema);\n const defaultVal = getDefault(schema);\n const desc = getDescription(schema);\n\n return {\n flag: `--${key}`,\n type: argType,\n required: isRequired(schema),\n description: desc,\n default: defaultVal,\n choices,\n typeLabel: describeType(schema),\n };\n}\n\n// ---------------------------------------------------------------------------\n// Help text formatting\n// ---------------------------------------------------------------------------\n\nconst COL_WIDTH = 36;\n\nfunction padEnd(str: string, width: number): string {\n return str.length >= width ? `${str} ` : str.padEnd(width);\n}\n\nfunction renderArg(arg: CliArgDefinition): string {\n const placeholder = buildValuePlaceholder(arg.type, arg.choices);\n const flagPart = placeholder ? `${arg.flag} ${placeholder}` : arg.flag;\n\n const typeAnnotation = arg.type === 'json' ? ` — ${arg.typeLabel}` : '';\n const defaultAnnotation = arg.default !== undefined ? ` [default: ${JSON.stringify(arg.default)}]` : '';\n const description = `${arg.description}${typeAnnotation}${defaultAnnotation}`.trim();\n\n return ` ${padEnd(flagPart, COL_WIDTH)}${description}`;\n}\n\nfunction formatHelp(args: CliArgDefinition[], options: { command?: string; description?: string }): string {\n const lines: string[] = [];\n\n const commandName = options.command ?? '<tool>';\n lines.push(`Usage: ${commandName} [options]`);\n\n if (options.description) {\n lines.push('');\n lines.push(options.description);\n }\n\n const required = args.filter((a) => a.required);\n const optional = args.filter((a) => !a.required);\n\n if (required.length > 0) {\n lines.push('');\n lines.push('Required:');\n for (const arg of required) {\n lines.push(renderArg(arg));\n }\n }\n\n if (optional.length > 0) {\n lines.push('');\n lines.push('Optional:');\n for (const arg of optional) {\n lines.push(renderArg(arg));\n }\n }\n\n return lines.join('\\n');\n}\n\n// ---------------------------------------------------------------------------\n// Public API\n// ---------------------------------------------------------------------------\n\n/**\n * Converts a ZodObject schema to:\n * - `args`: structured CliArgDefinition[] for programmatic use (e.g. parsing)\n * - `help`: formatted help string equivalent to `--help` output\n *\n * Enables AI agents to inspect a tool's expected arguments as CLI flags,\n * then reconstruct a valid call using {@link cliArgsToObject}.\n *\n * @example\n * const { help } = zodToCliArgs(RunSpecToolInputSchema, { command: 'run_spec' });\n * console.log(help);\n * // Usage: run_spec [options]\n * //\n * // Required:\n * // --specPath <string> Absolute path to the spec file\n * //\n * // Optional:\n * // --headless Run in headless mode [default: true]\n * // --env <json> Environment variables — Record<string, string>\n */\nexport function zodToCliArgs(\n schema: z.ZodObject<z.ZodRawShape>,\n options?: { command?: string; description?: string },\n): CliArgsResult {\n const args = Object.entries(schema.shape).map(([key, fieldSchema]) =>\n fieldToCliArg(key, fieldSchema as unknown as ZodLike),\n );\n\n const help = formatHelp(args, options ?? {});\n\n return { args, help };\n}\n","import { z } from 'zod';\nimport { zodToCliArgs } from './zodToCliArgs.js';\n\n// ---------------------------------------------------------------------------\n// Key normalisation\n// ---------------------------------------------------------------------------\n\n/**\n * Converts a CLI flag name (without --) to a camelCase object key.\n * Supports both kebab-case and camelCase input:\n * 'spec-path' → 'specPath'\n * 'specPath' → 'specPath'\n * 'base-url' → 'baseURL' (only uppercases the first letter after -)\n */\nfunction flagToKey(flag: string): string {\n // strip leading -- if present\n const raw = flag.startsWith('--') ? flag.slice(2) : flag;\n // kebab-case → camelCase\n return raw.replace(/-([a-z])/gi, (_, c: string) => c.toUpperCase());\n}\n\n// ---------------------------------------------------------------------------\n// Public API\n// ---------------------------------------------------------------------------\n\n/**\n * Parses a CLI argv array (e.g. process.argv.slice(2)) into a\n * Record<string, unknown> that can be validated by a Zod schema.\n *\n * Uses the schema to determine which flags are booleans (no value expected)\n * and which expect a JSON value (auto-parsed). The result can be passed\n * directly to {@link coerceArgs} or schema.parse().\n *\n * Parsing rules:\n * --flag (boolean in schema) → { flag: true }\n * --no-flag → { flag: false }\n * --key value (json in schema) → { key: JSON.parse(value) }\n * --key value (number in schema) → { key: parseFloat(value) }\n * --key value (string/default) → { key: value }\n * Kebab-case flags are converted to camelCase automatically.\n *\n * @example\n * const obj = cliArgsToObject(\n * ['--specPath', '/tests/foo.spec.ts', '--headless', '--env', '{\"KEY\":\"val\"}'],\n * RunSpecToolInputSchema,\n * );\n * // { specPath: '/tests/foo.spec.ts', headless: true, env: { KEY: 'val' } }\n */\nexport function cliArgsToObject(argv: string[], schema: z.ZodObject<z.ZodRawShape>): Record<string, unknown> {\n const { args: argDefs } = zodToCliArgs(schema);\n\n // Build lookup maps: both camelCase and kebab forms → CliArgDefinition\n const byKey = new Map(argDefs.map((d) => [flagToKey(d.flag), d]));\n // Also support kebab-case lookups (the flag already starts with --)\n const byFlag = new Map(argDefs.map((d) => [d.flag, d]));\n\n const result: Record<string, unknown> = {};\n\n let i = 0;\n while (i < argv.length) {\n const token = argv[i];\n\n if (!token.startsWith('--')) {\n i++;\n continue;\n }\n\n // Handle --no-<flag> negation\n if (token.startsWith('--no-')) {\n const key = flagToKey(token.slice(5)); // strip --no-\n result[key] = false;\n i++;\n continue;\n }\n\n // Support --key=value syntax\n const eqIdx = token.indexOf('=');\n let flagToken: string;\n let inlineValue: string | undefined;\n\n if (eqIdx !== -1) {\n flagToken = token.slice(0, eqIdx);\n inlineValue = token.slice(eqIdx + 1);\n } else {\n flagToken = token;\n inlineValue = undefined;\n }\n\n const key = flagToKey(flagToken);\n const argDef = byKey.get(key) ?? byFlag.get(flagToken);\n\n // Boolean flags: presence alone means true\n if (argDef?.type === 'boolean') {\n result[key] = true;\n i++;\n continue;\n }\n\n // Determine the value: inline (--key=val) or next token\n let rawValue: string | undefined;\n if (inlineValue !== undefined) {\n rawValue = inlineValue;\n i++;\n } else if (i + 1 < argv.length && !argv[i + 1].startsWith('--')) {\n rawValue = argv[i + 1];\n i += 2;\n } else {\n // No value token following — treat as boolean true\n result[key] = true;\n i++;\n continue;\n }\n\n // Parse value based on schema type\n if (argDef?.type === 'json') {\n try {\n result[key] = JSON.parse(rawValue);\n } catch {\n result[key] = rawValue;\n }\n } else if (argDef?.type === 'number') {\n const parsed = Number.parseFloat(rawValue);\n result[key] = Number.isNaN(parsed) ? rawValue : parsed;\n } else {\n result[key] = rawValue;\n }\n }\n\n return result;\n}\n","import { z } from 'zod';\n\n// ---------------------------------------------------------------------------\n// Internal helpers\n// ---------------------------------------------------------------------------\n\ntype JsonSchemaNode = Record<string, unknown>;\n\n/**\n * Convert a single JSON Schema property node to a Zod type.\n * Handles: string, number, integer, boolean, null, array, object,\n * anyOf/oneOf, enum, and array-of-types (e.g. [\"string\",\"null\"]).\n */\nfunction propertyToZod(node: unknown): z.ZodTypeAny {\n if (!node || typeof node !== 'object' || Array.isArray(node)) return z.unknown();\n const n = node as JsonSchemaNode;\n\n // anyOf / oneOf → union\n const variants = (n.anyOf ?? n.oneOf) as unknown[] | undefined;\n if (Array.isArray(variants) && variants.length > 0) {\n const members = variants.map(propertyToZod);\n if (members.length === 1) return members[0];\n return z.union([members[0], members[1], ...members.slice(2)] as [z.ZodTypeAny, z.ZodTypeAny, ...z.ZodTypeAny[]]);\n }\n\n // enum\n if (Array.isArray(n.enum) && n.enum.every((v) => typeof v === 'string')) {\n const [first, second, ...rest] = n.enum as string[];\n if (first === undefined) return z.unknown();\n if (second === undefined) return z.literal(first);\n return z.enum([first, second, ...rest]);\n }\n\n const type = n.type;\n\n // Array-of-types: [\"string\", \"null\"] → optional string\n if (Array.isArray(type)) {\n const nonNull = type.filter((t) => t !== 'null') as string[];\n const nullable = type.includes('null');\n if (nonNull.length === 0) return nullable ? z.null() : z.unknown();\n const inner =\n nonNull.length === 1\n ? propertyToZod({ ...n, type: nonNull[0] })\n : z.union(\n nonNull.map((t) => propertyToZod({ ...n, type: t })) as [z.ZodTypeAny, z.ZodTypeAny, ...z.ZodTypeAny[]],\n );\n return nullable ? z.union([inner, z.null()]) : inner;\n }\n\n if (type === 'string') return z.string();\n if (type === 'number' || type === 'integer') return z.number();\n if (type === 'boolean') return z.boolean();\n if (type === 'null') return z.null();\n\n if (type === 'array') {\n const items = n.items ? propertyToZod(n.items) : z.unknown();\n return z.array(items);\n }\n\n if (type === 'object') {\n if (n.properties && typeof n.properties === 'object' && !Array.isArray(n.properties)) {\n return jsonSchemaToZod(n);\n }\n return z.record(z.string(), z.unknown());\n }\n\n return z.unknown();\n}\n\n// ---------------------------------------------------------------------------\n// Public API\n// ---------------------------------------------------------------------------\n\n/**\n * Convert a JSON Schema object definition to a Zod object schema.\n *\n * Handles `properties`, `required`, `anyOf`/`oneOf`, `enum`, and the\n * common scalar types. Fields not listed in `required` are made optional.\n * Unknown/unsupported nodes map to `z.unknown()`.\n *\n * This is intentionally non-exhaustive: the goal is accurate type\n * classification for coercion (primitive vs non-primitive), not strict\n * schema validation.\n *\n * @example\n * const schema = jsonSchemaToZod({\n * type: 'object',\n * properties: {\n * env: { type: 'object' },\n * headless: { type: 'boolean' },\n * },\n * required: ['env'],\n * });\n * // schema.shape.env → ZodRecord (non-primitive → will be JSON.parsed if string)\n * // schema.shape.headless → ZodOptional<ZodBoolean>\n */\nexport function jsonSchemaToZod(schema: Record<string, unknown>): z.ZodObject<z.ZodRawShape> {\n const properties = schema.properties as Record<string, unknown> | undefined;\n const required = new Set<string>(Array.isArray(schema.required) ? (schema.required as string[]) : []);\n\n if (!properties) return z.object({});\n\n const shape: Record<string, z.ZodTypeAny> = {};\n for (const [key, prop] of Object.entries(properties)) {\n const zodType = propertyToZod(prop);\n shape[key] = required.has(key) ? zodType : zodType.optional();\n }\n\n return z.object(shape);\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.cjs","names":["defType","defType","defInnerType","isRequired","z"],"sources":["../src/utils/coerceArgs.ts","../src/utils/formatZodError.ts","../src/utils/zodToCliArgs.ts","../src/utils/cliArgsToObject.ts","../src/utils/jsonSchemaToZod.ts"],"sourcesContent":["import { z } from 'zod';\n\n// ---------------------------------------------------------------------------\n// Internal helpers — Zod v4 compatible\n// ---------------------------------------------------------------------------\n\n// Zod v4 schema shapes expose $ZodType internally; use a structural interface\n// to avoid the public ZodType vs $ZodType mismatch.\ninterface ZodLike {\n _def: { type?: string; innerType?: ZodLike; options?: ZodLike[] };\n}\n\nfunction defType(schema: ZodLike): string {\n return schema._def.type ?? '';\n}\n\nfunction unwrapZodLike(schema: ZodLike): ZodLike {\n const t = defType(schema);\n if (t === 'optional' || t === 'nullable' || t === 'default') {\n const inner = schema._def.innerType;\n return inner ? unwrapZodLike(inner) : schema;\n }\n return schema;\n}\n\nfunction isNonPrimitive(schema: ZodLike): boolean {\n const core = unwrapZodLike(schema);\n const t = defType(core);\n if (t === 'object' || t === 'array' || t === 'record') return true;\n if (t === 'union') {\n return (core._def.options ?? []).some(isNonPrimitive);\n }\n return false;\n}\n\n// ---------------------------------------------------------------------------\n// Public API\n// ---------------------------------------------------------------------------\n\n/**\n * Walks a ZodObject's shape and, for any field that expects a non-primitive\n * type (object, array, record, or union containing one), attempts to\n * JSON.parse string values. Leaves the value unchanged if:\n * - it is not a string\n * - the schema expects a primitive\n * - the string is not valid JSON\n *\n * This handles the common Claude Code behaviour of stringifying nested args\n * (e.g. env: '{\"KEY\":\"val\"}' instead of env: { KEY: 'val' }).\n */\nexport function coerceArgs(args: Record<string, unknown>, schema: z.ZodObject<z.ZodRawShape>): Record<string, unknown> {\n const result = { ...args };\n\n for (const [key, rawSchema] of Object.entries(schema.shape)) {\n const value = result[key];\n if (typeof value !== 'string') continue;\n if (!isNonPrimitive(rawSchema as unknown as ZodLike)) continue;\n\n try {\n result[key] = JSON.parse(value);\n } catch {\n // keep as string — not valid JSON\n }\n }\n\n return result;\n}\n","import { z } from 'zod';\n\n// ---------------------------------------------------------------------------\n// Internal schema introspection — Zod v4 compatible\n// ---------------------------------------------------------------------------\n\n// Structural interface compatible with both $ZodType (internal) and ZodType (public)\ninterface ZodLike {\n _def: {\n type?: string;\n innerType?: ZodLike;\n element?: ZodLike;\n valueType?: ZodLike;\n options?: readonly ZodLike[];\n value?: unknown;\n };\n description?: string;\n}\n\nfunction defType(schema: ZodLike): string {\n return schema._def.type ?? '';\n}\n\nfunction defInnerType(schema: ZodLike): ZodLike | undefined {\n return schema._def.innerType;\n}\n\nfunction isRequired(schema: ZodLike): boolean {\n const t = defType(schema);\n return t !== 'optional' && t !== 'default';\n}\n\n/**\n * Produces a concise human-readable type label for a Zod schema.\n * Examples: 'string', 'string[]', 'Record<string, string>', 'enum [a, b]'\n */\nexport function describeType(schema: ZodLike): string {\n const t = defType(schema);\n switch (t) {\n case 'string':\n return 'string';\n case 'number':\n return 'number';\n case 'boolean':\n return 'boolean';\n case 'bigint':\n return 'bigint';\n case 'null':\n return 'null';\n case 'undefined':\n return 'undefined';\n case 'any':\n return 'any';\n case 'unknown':\n return 'unknown';\n case 'literal':\n return JSON.stringify(schema._def.value);\n case 'enum': {\n // ZodEnum in v4 exposes .options as a getter\n const opts = (schema as unknown as { options: string[] }).options ?? [];\n return `enum [${opts.join(', ')}]`;\n }\n case 'array': {\n const el = schema._def.element;\n return el ? `${describeType(el)}[]` : 'unknown[]';\n }\n case 'record': {\n const valType = schema._def.valueType;\n return valType ? `Record<string, ${describeType(valType)}>` : 'Record<string, unknown>';\n }\n case 'object':\n return 'object';\n case 'optional':\n case 'nullable':\n case 'default': {\n const inner = defInnerType(schema);\n return inner ? describeType(inner) : 'unknown';\n }\n case 'union': {\n const opts = schema._def.options ?? [];\n return opts.map(describeType).join(' | ');\n }\n default:\n return 'unknown';\n }\n}\n\n// ---------------------------------------------------------------------------\n// Issue formatting — Zod v4 issue shapes\n// ---------------------------------------------------------------------------\n\n// Zod v4 uses 'invalid_value' (not 'invalid_enum_value') for enum violations.\n// Use string cast on issue.code to avoid ZodIssueCode constraint errors.\n\ninterface InvalidTypeIssueV4 {\n code: string;\n expected: string;\n message: string;\n path: (string | number)[];\n}\n\ninterface InvalidValueIssueV4 {\n code: string;\n values: (string | number)[];\n message: string;\n path: (string | number)[];\n}\n\ninterface TooSmallIssueV4 {\n code: string;\n minimum: number | bigint;\n inclusive: boolean;\n message: string;\n path: (string | number)[];\n}\n\ninterface TooBigIssueV4 {\n code: string;\n maximum: number | bigint;\n inclusive: boolean;\n message: string;\n path: (string | number)[];\n}\n\ninterface UnrecognizedKeysIssueV4 {\n code: string;\n keys: string[];\n message: string;\n path: (string | number)[];\n}\n\nfunction extractReceived(message: string): string | undefined {\n return message.match(/received (\\w+)(?:\\s|$)/)?.[1];\n}\n\nfunction formatIssueMessage(issue: z.ZodIssue): string {\n const code = issue.code as string;\n switch (code) {\n case 'invalid_type': {\n const i = issue as unknown as InvalidTypeIssueV4;\n const received = extractReceived(i.message);\n if (received === 'undefined') return 'Required field is missing';\n return i.message;\n }\n // Zod v4 uses 'invalid_value' for enum violations\n case 'invalid_value': {\n const i = issue as unknown as InvalidValueIssueV4;\n return `Invalid value — must be one of: ${i.values.join(', ')}`;\n }\n case 'too_small': {\n const i = issue as unknown as TooSmallIssueV4;\n return `Value too small — minimum is ${String(i.minimum)}${i.inclusive ? ' (inclusive)' : ' (exclusive)'}`;\n }\n case 'too_big': {\n const i = issue as unknown as TooBigIssueV4;\n return `Value too large — maximum is ${String(i.maximum)}${i.inclusive ? ' (inclusive)' : ' (exclusive)'}`;\n }\n case 'unrecognized_keys': {\n const i = issue as unknown as UnrecognizedKeysIssueV4;\n return `Unrecognized keys: ${i.keys.join(', ')}`;\n }\n default:\n return issue.message;\n }\n}\n\nfunction getActionableHint(issue: z.ZodIssue, fieldPath: string, fieldSchema: ZodLike | undefined): string | undefined {\n const flag = `--${fieldPath}`;\n const code = issue.code as string;\n\n switch (code) {\n case 'invalid_type': {\n const i = issue as unknown as InvalidTypeIssueV4;\n const received = extractReceived(i.message);\n\n if (received === 'undefined') {\n const typeLabel = fieldSchema ? describeType(fieldSchema) : 'value';\n return `Provide: ${flag} <${typeLabel}>`;\n }\n\n if (received === 'string' && (i.expected === 'record' || i.expected === 'array' || i.expected === 'object')) {\n return `Received a JSON string instead of ${i.expected}.\\n → The coercion layer should handle this automatically.\\n → CLI usage: ${flag} '<json ${i.expected}>'`;\n }\n\n return undefined;\n }\n\n case 'invalid_value': {\n const i = issue as unknown as InvalidValueIssueV4;\n const example = i.values[0];\n return `Use: ${flag} ${String(example)}`;\n }\n\n default:\n return undefined;\n }\n}\n\nfunction getFieldSchema(pathSegments: string[], schema: z.ZodObject<z.ZodRawShape>): ZodLike | undefined {\n if (pathSegments.length === 0) return undefined;\n return schema.shape[pathSegments[0]] as unknown as ZodLike | undefined;\n}\n\n// ---------------------------------------------------------------------------\n// Public API\n// ---------------------------------------------------------------------------\n\n/**\n * Converts a ZodError into a multi-line string optimized for AI agents.\n *\n * Each field with errors shows:\n * - field name, whether it is required/optional, and its expected type\n * - a concise description of what went wrong\n * - a concrete actionable hint (e.g. CLI flag usage)\n *\n * Detecting stringified objects: when the error says \"expected record/array,\n * received string\", it calls out the common Claude Code serialisation issue\n * and explains that the coercion layer should handle it automatically.\n *\n * @example\n * try {\n * schema.parse(args);\n * } catch (err) {\n * if (err instanceof z.ZodError) {\n * console.error(formatZodError(err, { schemaName: 'run_spec', schema }));\n * }\n * }\n */\nexport function formatZodError(\n error: z.ZodError,\n options?: { schemaName?: string; schema?: z.ZodObject<z.ZodRawShape> },\n): string {\n const { schemaName, schema } = options ?? {};\n\n // Group issues by dotted path\n const byPath = new Map<string, z.ZodIssue[]>();\n for (const issue of error.issues) {\n const path = issue.path.length > 0 ? issue.path.map(String).join('.') : '(root)';\n const existing = byPath.get(path) ?? [];\n existing.push(issue);\n byPath.set(path, existing);\n }\n\n const header = schemaName ? `Validation failed for \"${schemaName}\":` : 'Validation failed:';\n const lines: string[] = [header];\n\n for (const [path, issues] of byPath) {\n lines.push('');\n\n const fieldSchema = schema ? getFieldSchema(path.split('.'), schema) : undefined;\n const required = fieldSchema\n ? isRequired(fieldSchema)\n : issues.some((i) => {\n if ((i.code as string) !== 'invalid_type') return false;\n const msg = (i as unknown as { message: string }).message;\n return extractReceived(msg) === 'undefined';\n });\n\n const typeDesc = fieldSchema ? describeType(fieldSchema) : '';\n const meta = `(${required ? 'required' : 'optional'})${typeDesc ? ` — ${typeDesc}` : ''}`;\n\n lines.push(` • ${path} ${meta}`);\n\n for (const issue of issues) {\n lines.push(` ✗ ${formatIssueMessage(issue)}`);\n const hint = getActionableHint(issue, path, fieldSchema);\n if (hint) {\n lines.push(` → ${hint}`);\n }\n }\n }\n\n return lines.join('\\n');\n}\n","import { z } from 'zod';\nimport type { CliArgDefinition, CliArgType, CliArgsResult } from '../types/index.js';\nimport { describeType } from './formatZodError.js';\n\n// ---------------------------------------------------------------------------\n// Internal helpers — Zod v4 compatible\n// ---------------------------------------------------------------------------\n\n// Structural interface compatible with both $ZodType (internal) and ZodType (public)\ninterface ZodLike {\n _def: { type?: string; innerType?: ZodLike; defaultValue?: unknown; options?: readonly ZodLike[] };\n description?: string;\n}\n\nfunction defType(schema: ZodLike): string {\n return schema._def.type ?? '';\n}\n\nfunction defInnerType(schema: ZodLike): ZodLike | undefined {\n return schema._def.innerType;\n}\n\nfunction unwrapSchema(schema: ZodLike): ZodLike {\n const t = defType(schema);\n if (t === 'optional' || t === 'nullable' || t === 'default') {\n const inner = defInnerType(schema);\n return inner ? unwrapSchema(inner) : schema;\n }\n return schema;\n}\n\nfunction isRequired(schema: ZodLike): boolean {\n const t = defType(schema);\n return t !== 'optional' && t !== 'default';\n}\n\nfunction getDefault(schema: ZodLike): unknown {\n if (defType(schema) === 'default') {\n return schema._def.defaultValue;\n }\n return undefined;\n}\n\nfunction getDescription(schema: ZodLike): string {\n return schema.description ?? '';\n}\n\n/**\n * Maps a Zod schema field to a CliArgType used for help text and parsing.\n */\nfunction resolveCliType(schema: ZodLike): CliArgType {\n const core = unwrapSchema(schema);\n const t = defType(core);\n\n switch (t) {\n case 'boolean':\n return 'boolean';\n case 'number':\n return 'number';\n case 'object':\n case 'record':\n case 'array':\n return 'json';\n case 'union': {\n const opts: readonly ZodLike[] = core._def.options ?? [];\n const hasNonPrimitive = opts.some((o) => {\n const ot = defType(unwrapSchema(o));\n return ot === 'object' || ot === 'array' || ot === 'record';\n });\n return hasNonPrimitive ? 'json' : 'string';\n }\n default:\n return 'string';\n }\n}\n\n/**\n * Returns enum choices if the (unwrapped) schema is a ZodEnum.\n */\nfunction getChoices(schema: ZodLike): string[] | undefined {\n const core = unwrapSchema(schema);\n if (defType(core) === 'enum') {\n return (core as unknown as { options: string[] }).options;\n }\n return undefined;\n}\n\n/**\n * Builds the value placeholder shown in help text, e.g. '<string>', '<json>',\n * '<playwright|extension>'.\n */\nfunction buildValuePlaceholder(argType: CliArgType, choices?: string[]): string {\n if (choices && choices.length > 0) return `<${choices.join('|')}>`;\n switch (argType) {\n case 'boolean':\n return '';\n case 'number':\n return '<number>';\n case 'json':\n return '<json>';\n default:\n return '<string>';\n }\n}\n\n/**\n * Converts a single schema field to a CliArgDefinition.\n */\nfunction fieldToCliArg(key: string, schema: ZodLike): CliArgDefinition {\n const argType = resolveCliType(schema);\n const choices = getChoices(schema);\n const defaultVal = getDefault(schema);\n const desc = getDescription(schema);\n\n return {\n flag: `--${key}`,\n type: argType,\n required: isRequired(schema),\n description: desc,\n default: defaultVal,\n choices,\n typeLabel: describeType(schema),\n };\n}\n\n// ---------------------------------------------------------------------------\n// Help text formatting\n// ---------------------------------------------------------------------------\n\nconst COL_WIDTH = 36;\n\nfunction padEnd(str: string, width: number): string {\n return str.length >= width ? `${str} ` : str.padEnd(width);\n}\n\nfunction renderArg(arg: CliArgDefinition): string {\n const placeholder = buildValuePlaceholder(arg.type, arg.choices);\n const flagPart = placeholder ? `${arg.flag} ${placeholder}` : arg.flag;\n\n const typeAnnotation = arg.type === 'json' ? ` — ${arg.typeLabel}` : '';\n const defaultAnnotation = arg.default !== undefined ? ` [default: ${JSON.stringify(arg.default)}]` : '';\n const description = `${arg.description}${typeAnnotation}${defaultAnnotation}`.trim();\n\n return ` ${padEnd(flagPart, COL_WIDTH)}${description}`;\n}\n\nfunction formatHelp(args: CliArgDefinition[], options: { command?: string; description?: string }): string {\n const lines: string[] = [];\n\n const commandName = options.command ?? '<tool>';\n lines.push(`Usage: ${commandName} [options]`);\n\n if (options.description) {\n lines.push('');\n lines.push(options.description);\n }\n\n const required = args.filter((a) => a.required);\n const optional = args.filter((a) => !a.required);\n\n if (required.length > 0) {\n lines.push('');\n lines.push('Required:');\n for (const arg of required) {\n lines.push(renderArg(arg));\n }\n }\n\n if (optional.length > 0) {\n lines.push('');\n lines.push('Optional:');\n for (const arg of optional) {\n lines.push(renderArg(arg));\n }\n }\n\n return lines.join('\\n');\n}\n\n// ---------------------------------------------------------------------------\n// Public API\n// ---------------------------------------------------------------------------\n\n/**\n * Converts a ZodObject schema to:\n * - `args`: structured CliArgDefinition[] for programmatic use (e.g. parsing)\n * - `help`: formatted help string equivalent to `--help` output\n *\n * Enables AI agents to inspect a tool's expected arguments as CLI flags,\n * then reconstruct a valid call using {@link cliArgsToObject}.\n *\n * @example\n * const { help } = zodToCliArgs(RunSpecToolInputSchema, { command: 'run_spec' });\n * console.log(help);\n * // Usage: run_spec [options]\n * //\n * // Required:\n * // --specPath <string> Absolute path to the spec file\n * //\n * // Optional:\n * // --headless Run in headless mode [default: true]\n * // --env <json> Environment variables — Record<string, string>\n */\nexport function zodToCliArgs(\n schema: z.ZodObject<z.ZodRawShape>,\n options?: { command?: string; description?: string },\n): CliArgsResult {\n const args = Object.entries(schema.shape).map(([key, fieldSchema]) =>\n fieldToCliArg(key, fieldSchema as unknown as ZodLike),\n );\n\n const help = formatHelp(args, options ?? {});\n\n return { args, help };\n}\n","import { z } from 'zod';\nimport { zodToCliArgs } from './zodToCliArgs.js';\n\n// ---------------------------------------------------------------------------\n// Key normalisation\n// ---------------------------------------------------------------------------\n\n/**\n * Converts a CLI flag name (without --) to a camelCase object key.\n * Supports both kebab-case and camelCase input:\n * 'spec-path' → 'specPath'\n * 'specPath' → 'specPath'\n * 'base-url' → 'baseURL' (only uppercases the first letter after -)\n */\nfunction flagToKey(flag: string): string {\n // strip leading -- if present\n const raw = flag.startsWith('--') ? flag.slice(2) : flag;\n // kebab-case → camelCase\n return raw.replace(/-([a-z])/gi, (_, c: string) => c.toUpperCase());\n}\n\n// ---------------------------------------------------------------------------\n// Public API\n// ---------------------------------------------------------------------------\n\n/**\n * Parses a CLI argv array (e.g. process.argv.slice(2)) into a\n * Record<string, unknown> that can be validated by a Zod schema.\n *\n * Uses the schema to determine which flags are booleans (no value expected)\n * and which expect a JSON value (auto-parsed). The result can be passed\n * directly to {@link coerceArgs} or schema.parse().\n *\n * Parsing rules:\n * --flag (boolean in schema) → { flag: true }\n * --no-flag → { flag: false }\n * --key value (json in schema) → { key: JSON.parse(value) }\n * --key value (number in schema) → { key: parseFloat(value) }\n * --key value (string/default) → { key: value }\n * Kebab-case flags are converted to camelCase automatically.\n *\n * @example\n * const obj = cliArgsToObject(\n * ['--specPath', '/tests/foo.spec.ts', '--headless', '--env', '{\"KEY\":\"val\"}'],\n * RunSpecToolInputSchema,\n * );\n * // { specPath: '/tests/foo.spec.ts', headless: true, env: { KEY: 'val' } }\n */\nexport function cliArgsToObject(argv: string[], schema: z.ZodObject<z.ZodRawShape>): Record<string, unknown> {\n const { args: argDefs } = zodToCliArgs(schema);\n\n // Build lookup maps: both camelCase and kebab forms → CliArgDefinition\n const byKey = new Map(argDefs.map((d) => [flagToKey(d.flag), d]));\n // Also support kebab-case lookups (the flag already starts with --)\n const byFlag = new Map(argDefs.map((d) => [d.flag, d]));\n\n const result: Record<string, unknown> = {};\n\n let i = 0;\n while (i < argv.length) {\n const token = argv[i];\n\n if (!token.startsWith('--')) {\n i++;\n continue;\n }\n\n // Handle --no-<flag> negation\n if (token.startsWith('--no-')) {\n const key = flagToKey(token.slice(5)); // strip --no-\n result[key] = false;\n i++;\n continue;\n }\n\n // Support --key=value syntax\n const eqIdx = token.indexOf('=');\n let flagToken: string;\n let inlineValue: string | undefined;\n\n if (eqIdx !== -1) {\n flagToken = token.slice(0, eqIdx);\n inlineValue = token.slice(eqIdx + 1);\n } else {\n flagToken = token;\n inlineValue = undefined;\n }\n\n const key = flagToKey(flagToken);\n const argDef = byKey.get(key) ?? byFlag.get(flagToken);\n\n // Boolean flags: presence alone means true\n if (argDef?.type === 'boolean') {\n result[key] = true;\n i++;\n continue;\n }\n\n // Determine the value: inline (--key=val) or next token\n let rawValue: string | undefined;\n if (inlineValue !== undefined) {\n rawValue = inlineValue;\n i++;\n } else if (i + 1 < argv.length && !argv[i + 1].startsWith('--')) {\n rawValue = argv[i + 1];\n i += 2;\n } else {\n // No value token following — treat as boolean true\n result[key] = true;\n i++;\n continue;\n }\n\n // Parse value based on schema type\n if (argDef?.type === 'json') {\n try {\n result[key] = JSON.parse(rawValue);\n } catch {\n result[key] = rawValue;\n }\n } else if (argDef?.type === 'number') {\n const parsed = Number.parseFloat(rawValue);\n result[key] = Number.isNaN(parsed) ? rawValue : parsed;\n } else {\n result[key] = rawValue;\n }\n }\n\n return result;\n}\n","import { z } from 'zod';\n\n// ---------------------------------------------------------------------------\n// Internal helpers\n// ---------------------------------------------------------------------------\n\ntype JsonSchemaNode = Record<string, unknown>;\n\n/**\n * Convert a single JSON Schema property node to a Zod type.\n * Handles: string, number, integer, boolean, null, array, object,\n * anyOf/oneOf, enum, and array-of-types (e.g. [\"string\",\"null\"]).\n */\nfunction propertyToZod(node: unknown): z.ZodTypeAny {\n if (!node || typeof node !== 'object' || Array.isArray(node)) return z.unknown();\n const n = node as JsonSchemaNode;\n\n // anyOf / oneOf → union\n const variants = (n.anyOf ?? n.oneOf) as unknown[] | undefined;\n if (Array.isArray(variants) && variants.length > 0) {\n const members = variants.map(propertyToZod);\n if (members.length === 1) return members[0];\n return z.union([members[0], members[1], ...members.slice(2)] as [z.ZodTypeAny, z.ZodTypeAny, ...z.ZodTypeAny[]]);\n }\n\n // enum\n if (Array.isArray(n.enum) && n.enum.every((v) => typeof v === 'string')) {\n const [first, second, ...rest] = n.enum as string[];\n if (first === undefined) return z.unknown();\n if (second === undefined) return z.literal(first);\n return z.enum([first, second, ...rest]);\n }\n\n const type = n.type;\n\n // Array-of-types: [\"string\", \"null\"] → optional string\n if (Array.isArray(type)) {\n const nonNull = type.filter((t) => t !== 'null') as string[];\n const nullable = type.includes('null');\n if (nonNull.length === 0) return nullable ? z.null() : z.unknown();\n const inner =\n nonNull.length === 1\n ? propertyToZod({ ...n, type: nonNull[0] })\n : z.union(\n nonNull.map((t) => propertyToZod({ ...n, type: t })) as [z.ZodTypeAny, z.ZodTypeAny, ...z.ZodTypeAny[]],\n );\n return nullable ? z.union([inner, z.null()]) : inner;\n }\n\n if (type === 'string') return z.string();\n if (type === 'number' || type === 'integer') return z.number();\n if (type === 'boolean') return z.boolean();\n if (type === 'null') return z.null();\n\n if (type === 'array') {\n const items = n.items ? propertyToZod(n.items) : z.unknown();\n return z.array(items);\n }\n\n if (type === 'object') {\n if (n.properties && typeof n.properties === 'object' && !Array.isArray(n.properties)) {\n return jsonSchemaToZod(n);\n }\n return z.record(z.string(), z.unknown());\n }\n\n return z.unknown();\n}\n\n// ---------------------------------------------------------------------------\n// Public API\n// ---------------------------------------------------------------------------\n\n/**\n * Convert a JSON Schema object definition to a Zod object schema.\n *\n * Handles `properties`, `required`, `anyOf`/`oneOf`, `enum`, and the\n * common scalar types. Fields not listed in `required` are made optional.\n * Unknown/unsupported nodes map to `z.unknown()`.\n *\n * This is intentionally non-exhaustive: the goal is accurate type\n * classification for coercion (primitive vs non-primitive), not strict\n * schema validation.\n *\n * @example\n * const schema = jsonSchemaToZod({\n * type: 'object',\n * properties: {\n * env: { type: 'object' },\n * headless: { type: 'boolean' },\n * },\n * required: ['env'],\n * });\n * // schema.shape.env → ZodRecord (non-primitive → will be JSON.parsed if string)\n * // schema.shape.headless → ZodOptional<ZodBoolean>\n */\nexport function jsonSchemaToZod(schema: Record<string, unknown>): z.ZodObject<z.ZodRawShape> {\n const properties = schema.properties as Record<string, unknown> | undefined;\n const required = new Set<string>(Array.isArray(schema.required) ? (schema.required as string[]) : []);\n\n if (!properties) return z.object({});\n\n const shape: Record<string, z.ZodTypeAny> = {};\n for (const [key, prop] of Object.entries(properties)) {\n const zodType = propertyToZod(prop);\n shape[key] = required.has(key) ? zodType : zodType.optional();\n }\n\n return z.object(shape);\n}\n"],"mappings":"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"}
|
package/dist/index.d.cts
CHANGED
package/dist/index.d.cts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.cts","names":[],"sources":["../src/types/index.ts","../src/utils/coerceArgs.ts","../src/utils/formatZodError.ts","../src/utils/zodToCliArgs.ts","../src/utils/cliArgsToObject.ts","../src/utils/jsonSchemaToZod.ts"],"
|
|
1
|
+
{"version":3,"file":"index.d.cts","names":[],"sources":["../src/types/index.ts","../src/utils/coerceArgs.ts","../src/utils/formatZodError.ts","../src/utils/zodToCliArgs.ts","../src/utils/cliArgsToObject.ts","../src/utils/jsonSchemaToZod.ts"],"mappings":";;;;;;AAWA;;;;;AAKA;;AALA,KAAY,UAAA;;;;UAKK,gBAAA;EAMf;EAJA,IAAA;EAQA;EANA,IAAA,EAAM,UAAA;EAUN;EARA,QAAA;EAQS;EANT,WAAA;EAY4B;EAV5B,OAAA;EAYsB;EAVtB,OAAA;EAUM;EARN,SAAA;AAAA;;;;UAMe,aAAA;ECcD;EDZd,IAAA,EAAM,gBAAA;;EAEN,IAAA;AAAA;;;;;AA7BF;;;;;AAKA;;;;iBCkCgB,UAAA,CAAW,IAAA,EAAM,MAAA,mBAAyB,MAAA,EAAQ,CAAA,CAAE,SAAA,CAAU,CAAA,CAAE,WAAA,IAAe,MAAA;;;UC3CrF,OAAA;EACR,IAAA;IACE,IAAA;IACA,SAAA,GAAY,OAAA;IACZ,OAAA,GAAU,OAAA;IACV,SAAA,GAAY,OAAA;IACZ,OAAA,YAAmB,OAAA;IACnB,KAAA;EAAA;EAEF,WAAA;AAAA;;;;;iBAoBc,YAAA,CAAa,MAAA,EAAQ,OAAA;;;;;;AFArC;;;;;;;;;;;;ACcA;;;;iBCkLgB,cAAA,CACd,KAAA,EAAO,CAAA,CAAE,QAAA,EACT,OAAA;EAAY,UAAA;EAAqB,MAAA,GAAS,CAAA,CAAE,SAAA,CAAU,CAAA,CAAE,WAAA;AAAA;;;;AF3N1D;;;;;AAKA;;;;;;;;;;;;;;iBG2LgB,YAAA,CACd,MAAA,EAAQ,CAAA,CAAE,SAAA,CAAU,CAAA,CAAE,WAAA,GACtB,OAAA;EAAY,OAAA;EAAkB,WAAA;AAAA,IAC7B,aAAA;;;;;AHnMH;;;;;AAKA;;;;;;;;;;;;;;AAoBA;;iBIYgB,eAAA,CAAgB,IAAA,YAAgB,MAAA,EAAQ,CAAA,CAAE,SAAA,CAAU,CAAA,CAAE,WAAA,IAAe,MAAA;;;;;AJrCrF;;;;;AAKA;;;;;;;;;;;;;;AAoBA;;iBK4DgB,eAAA,CAAgB,MAAA,EAAQ,MAAA,oBAA0B,CAAA,CAAE,SAAA,CAAU,CAAA,CAAE,WAAA"}
|
package/dist/index.d.mts
CHANGED
package/dist/index.d.mts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.mts","names":[],"sources":["../src/types/index.ts","../src/utils/coerceArgs.ts","../src/utils/formatZodError.ts","../src/utils/zodToCliArgs.ts","../src/utils/cliArgsToObject.ts","../src/utils/jsonSchemaToZod.ts"],"
|
|
1
|
+
{"version":3,"file":"index.d.mts","names":[],"sources":["../src/types/index.ts","../src/utils/coerceArgs.ts","../src/utils/formatZodError.ts","../src/utils/zodToCliArgs.ts","../src/utils/cliArgsToObject.ts","../src/utils/jsonSchemaToZod.ts"],"mappings":";;;;;;AAWA;;;;;AAKA;;AALA,KAAY,UAAA;;;;UAKK,gBAAA;EAMf;EAJA,IAAA;EAQA;EANA,IAAA,EAAM,UAAA;EAUN;EARA,QAAA;EAQS;EANT,WAAA;EAY4B;EAV5B,OAAA;EAYsB;EAVtB,OAAA;EAUM;EARN,SAAA;AAAA;;;;UAMe,aAAA;ECcD;EDZd,IAAA,EAAM,gBAAA;;EAEN,IAAA;AAAA;;;;;AA7BF;;;;;AAKA;;;;iBCkCgB,UAAA,CAAW,IAAA,EAAM,MAAA,mBAAyB,MAAA,EAAQ,CAAA,CAAE,SAAA,CAAU,CAAA,CAAE,WAAA,IAAe,MAAA;;;UC3CrF,OAAA;EACR,IAAA;IACE,IAAA;IACA,SAAA,GAAY,OAAA;IACZ,OAAA,GAAU,OAAA;IACV,SAAA,GAAY,OAAA;IACZ,OAAA,YAAmB,OAAA;IACnB,KAAA;EAAA;EAEF,WAAA;AAAA;;;;;iBAoBc,YAAA,CAAa,MAAA,EAAQ,OAAA;;;;;;AFArC;;;;;;;;;;;;ACcA;;;;iBCkLgB,cAAA,CACd,KAAA,EAAO,CAAA,CAAE,QAAA,EACT,OAAA;EAAY,UAAA;EAAqB,MAAA,GAAS,CAAA,CAAE,SAAA,CAAU,CAAA,CAAE,WAAA;AAAA;;;;AF3N1D;;;;;AAKA;;;;;;;;;;;;;;iBG2LgB,YAAA,CACd,MAAA,EAAQ,CAAA,CAAE,SAAA,CAAU,CAAA,CAAE,WAAA,GACtB,OAAA;EAAY,OAAA;EAAkB,WAAA;AAAA,IAC7B,aAAA;;;;;AHnMH;;;;;AAKA;;;;;;;;;;;;;;AAoBA;;iBIYgB,eAAA,CAAgB,IAAA,YAAgB,MAAA,EAAQ,CAAA,CAAE,SAAA,CAAU,CAAA,CAAE,WAAA,IAAe,MAAA;;;;;AJrCrF;;;;;AAKA;;;;;;;;;;;;;;AAoBA;;iBK4DgB,eAAA,CAAgB,MAAA,EAAQ,MAAA,oBAA0B,CAAA,CAAE,SAAA,CAAU,CAAA,CAAE,WAAA"}
|
package/dist/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.mjs","names":["defType","defType","defInnerType","isRequired","lines: string[]","lines: string[]","result: Record<string, unknown>","key","flagToken: string","inlineValue: string | undefined","rawValue: string | undefined","shape: Record<string, z.ZodTypeAny>"],"sources":["../src/utils/coerceArgs.ts","../src/utils/formatZodError.ts","../src/utils/zodToCliArgs.ts","../src/utils/cliArgsToObject.ts","../src/utils/jsonSchemaToZod.ts"],"sourcesContent":["import { z } from 'zod';\n\n// ---------------------------------------------------------------------------\n// Internal helpers — Zod v4 compatible\n// ---------------------------------------------------------------------------\n\n// Zod v4 schema shapes expose $ZodType internally; use a structural interface\n// to avoid the public ZodType vs $ZodType mismatch.\ninterface ZodLike {\n _def: { type?: string; innerType?: ZodLike; options?: ZodLike[] };\n}\n\nfunction defType(schema: ZodLike): string {\n return schema._def.type ?? '';\n}\n\nfunction unwrapZodLike(schema: ZodLike): ZodLike {\n const t = defType(schema);\n if (t === 'optional' || t === 'nullable' || t === 'default') {\n const inner = schema._def.innerType;\n return inner ? unwrapZodLike(inner) : schema;\n }\n return schema;\n}\n\nfunction isNonPrimitive(schema: ZodLike): boolean {\n const core = unwrapZodLike(schema);\n const t = defType(core);\n if (t === 'object' || t === 'array' || t === 'record') return true;\n if (t === 'union') {\n return (core._def.options ?? []).some(isNonPrimitive);\n }\n return false;\n}\n\n// ---------------------------------------------------------------------------\n// Public API\n// ---------------------------------------------------------------------------\n\n/**\n * Walks a ZodObject's shape and, for any field that expects a non-primitive\n * type (object, array, record, or union containing one), attempts to\n * JSON.parse string values. Leaves the value unchanged if:\n * - it is not a string\n * - the schema expects a primitive\n * - the string is not valid JSON\n *\n * This handles the common Claude Code behaviour of stringifying nested args\n * (e.g. env: '{\"KEY\":\"val\"}' instead of env: { KEY: 'val' }).\n */\nexport function coerceArgs(args: Record<string, unknown>, schema: z.ZodObject<z.ZodRawShape>): Record<string, unknown> {\n const result = { ...args };\n\n for (const [key, rawSchema] of Object.entries(schema.shape)) {\n const value = result[key];\n if (typeof value !== 'string') continue;\n if (!isNonPrimitive(rawSchema as unknown as ZodLike)) continue;\n\n try {\n result[key] = JSON.parse(value);\n } catch {\n // keep as string — not valid JSON\n }\n }\n\n return result;\n}\n","import { z } from 'zod';\n\n// ---------------------------------------------------------------------------\n// Internal schema introspection — Zod v4 compatible\n// ---------------------------------------------------------------------------\n\n// Structural interface compatible with both $ZodType (internal) and ZodType (public)\ninterface ZodLike {\n _def: {\n type?: string;\n innerType?: ZodLike;\n element?: ZodLike;\n valueType?: ZodLike;\n options?: readonly ZodLike[];\n value?: unknown;\n };\n description?: string;\n}\n\nfunction defType(schema: ZodLike): string {\n return schema._def.type ?? '';\n}\n\nfunction defInnerType(schema: ZodLike): ZodLike | undefined {\n return schema._def.innerType;\n}\n\nfunction isRequired(schema: ZodLike): boolean {\n const t = defType(schema);\n return t !== 'optional' && t !== 'default';\n}\n\n/**\n * Produces a concise human-readable type label for a Zod schema.\n * Examples: 'string', 'string[]', 'Record<string, string>', 'enum [a, b]'\n */\nexport function describeType(schema: ZodLike): string {\n const t = defType(schema);\n switch (t) {\n case 'string':\n return 'string';\n case 'number':\n return 'number';\n case 'boolean':\n return 'boolean';\n case 'bigint':\n return 'bigint';\n case 'null':\n return 'null';\n case 'undefined':\n return 'undefined';\n case 'any':\n return 'any';\n case 'unknown':\n return 'unknown';\n case 'literal':\n return JSON.stringify(schema._def.value);\n case 'enum': {\n // ZodEnum in v4 exposes .options as a getter\n const opts = (schema as unknown as { options: string[] }).options ?? [];\n return `enum [${opts.join(', ')}]`;\n }\n case 'array': {\n const el = schema._def.element;\n return el ? `${describeType(el)}[]` : 'unknown[]';\n }\n case 'record': {\n const valType = schema._def.valueType;\n return valType ? `Record<string, ${describeType(valType)}>` : 'Record<string, unknown>';\n }\n case 'object':\n return 'object';\n case 'optional':\n case 'nullable':\n case 'default': {\n const inner = defInnerType(schema);\n return inner ? describeType(inner) : 'unknown';\n }\n case 'union': {\n const opts = schema._def.options ?? [];\n return opts.map(describeType).join(' | ');\n }\n default:\n return 'unknown';\n }\n}\n\n// ---------------------------------------------------------------------------\n// Issue formatting — Zod v4 issue shapes\n// ---------------------------------------------------------------------------\n\n// Zod v4 uses 'invalid_value' (not 'invalid_enum_value') for enum violations.\n// Use string cast on issue.code to avoid ZodIssueCode constraint errors.\n\ninterface InvalidTypeIssueV4 {\n code: string;\n expected: string;\n message: string;\n path: (string | number)[];\n}\n\ninterface InvalidValueIssueV4 {\n code: string;\n values: (string | number)[];\n message: string;\n path: (string | number)[];\n}\n\ninterface TooSmallIssueV4 {\n code: string;\n minimum: number | bigint;\n inclusive: boolean;\n message: string;\n path: (string | number)[];\n}\n\ninterface TooBigIssueV4 {\n code: string;\n maximum: number | bigint;\n inclusive: boolean;\n message: string;\n path: (string | number)[];\n}\n\ninterface UnrecognizedKeysIssueV4 {\n code: string;\n keys: string[];\n message: string;\n path: (string | number)[];\n}\n\nfunction extractReceived(message: string): string | undefined {\n return message.match(/received (\\w+)(?:\\s|$)/)?.[1];\n}\n\nfunction formatIssueMessage(issue: z.ZodIssue): string {\n const code = issue.code as string;\n switch (code) {\n case 'invalid_type': {\n const i = issue as unknown as InvalidTypeIssueV4;\n const received = extractReceived(i.message);\n if (received === 'undefined') return 'Required field is missing';\n return i.message;\n }\n // Zod v4 uses 'invalid_value' for enum violations\n case 'invalid_value': {\n const i = issue as unknown as InvalidValueIssueV4;\n return `Invalid value — must be one of: ${i.values.join(', ')}`;\n }\n case 'too_small': {\n const i = issue as unknown as TooSmallIssueV4;\n return `Value too small — minimum is ${String(i.minimum)}${i.inclusive ? ' (inclusive)' : ' (exclusive)'}`;\n }\n case 'too_big': {\n const i = issue as unknown as TooBigIssueV4;\n return `Value too large — maximum is ${String(i.maximum)}${i.inclusive ? ' (inclusive)' : ' (exclusive)'}`;\n }\n case 'unrecognized_keys': {\n const i = issue as unknown as UnrecognizedKeysIssueV4;\n return `Unrecognized keys: ${i.keys.join(', ')}`;\n }\n default:\n return issue.message;\n }\n}\n\nfunction getActionableHint(issue: z.ZodIssue, fieldPath: string, fieldSchema: ZodLike | undefined): string | undefined {\n const flag = `--${fieldPath}`;\n const code = issue.code as string;\n\n switch (code) {\n case 'invalid_type': {\n const i = issue as unknown as InvalidTypeIssueV4;\n const received = extractReceived(i.message);\n\n if (received === 'undefined') {\n const typeLabel = fieldSchema ? describeType(fieldSchema) : 'value';\n return `Provide: ${flag} <${typeLabel}>`;\n }\n\n if (received === 'string' && (i.expected === 'record' || i.expected === 'array' || i.expected === 'object')) {\n return `Received a JSON string instead of ${i.expected}.\\n → The coercion layer should handle this automatically.\\n → CLI usage: ${flag} '<json ${i.expected}>'`;\n }\n\n return undefined;\n }\n\n case 'invalid_value': {\n const i = issue as unknown as InvalidValueIssueV4;\n const example = i.values[0];\n return `Use: ${flag} ${String(example)}`;\n }\n\n default:\n return undefined;\n }\n}\n\nfunction getFieldSchema(pathSegments: string[], schema: z.ZodObject<z.ZodRawShape>): ZodLike | undefined {\n if (pathSegments.length === 0) return undefined;\n return schema.shape[pathSegments[0]] as unknown as ZodLike | undefined;\n}\n\n// ---------------------------------------------------------------------------\n// Public API\n// ---------------------------------------------------------------------------\n\n/**\n * Converts a ZodError into a multi-line string optimized for AI agents.\n *\n * Each field with errors shows:\n * - field name, whether it is required/optional, and its expected type\n * - a concise description of what went wrong\n * - a concrete actionable hint (e.g. CLI flag usage)\n *\n * Detecting stringified objects: when the error says \"expected record/array,\n * received string\", it calls out the common Claude Code serialisation issue\n * and explains that the coercion layer should handle it automatically.\n *\n * @example\n * try {\n * schema.parse(args);\n * } catch (err) {\n * if (err instanceof z.ZodError) {\n * console.error(formatZodError(err, { schemaName: 'run_spec', schema }));\n * }\n * }\n */\nexport function formatZodError(\n error: z.ZodError,\n options?: { schemaName?: string; schema?: z.ZodObject<z.ZodRawShape> },\n): string {\n const { schemaName, schema } = options ?? {};\n\n // Group issues by dotted path\n const byPath = new Map<string, z.ZodIssue[]>();\n for (const issue of error.issues) {\n const path = issue.path.length > 0 ? issue.path.map(String).join('.') : '(root)';\n const existing = byPath.get(path) ?? [];\n existing.push(issue);\n byPath.set(path, existing);\n }\n\n const header = schemaName ? `Validation failed for \"${schemaName}\":` : 'Validation failed:';\n const lines: string[] = [header];\n\n for (const [path, issues] of byPath) {\n lines.push('');\n\n const fieldSchema = schema ? getFieldSchema(path.split('.'), schema) : undefined;\n const required = fieldSchema\n ? isRequired(fieldSchema)\n : issues.some((i) => {\n if ((i.code as string) !== 'invalid_type') return false;\n const msg = (i as unknown as { message: string }).message;\n return extractReceived(msg) === 'undefined';\n });\n\n const typeDesc = fieldSchema ? describeType(fieldSchema) : '';\n const meta = `(${required ? 'required' : 'optional'})${typeDesc ? ` — ${typeDesc}` : ''}`;\n\n lines.push(` • ${path} ${meta}`);\n\n for (const issue of issues) {\n lines.push(` ✗ ${formatIssueMessage(issue)}`);\n const hint = getActionableHint(issue, path, fieldSchema);\n if (hint) {\n lines.push(` → ${hint}`);\n }\n }\n }\n\n return lines.join('\\n');\n}\n","import { z } from 'zod';\nimport type { CliArgDefinition, CliArgType, CliArgsResult } from '../types/index.js';\nimport { describeType } from './formatZodError.js';\n\n// ---------------------------------------------------------------------------\n// Internal helpers — Zod v4 compatible\n// ---------------------------------------------------------------------------\n\n// Structural interface compatible with both $ZodType (internal) and ZodType (public)\ninterface ZodLike {\n _def: { type?: string; innerType?: ZodLike; defaultValue?: unknown; options?: readonly ZodLike[] };\n description?: string;\n}\n\nfunction defType(schema: ZodLike): string {\n return schema._def.type ?? '';\n}\n\nfunction defInnerType(schema: ZodLike): ZodLike | undefined {\n return schema._def.innerType;\n}\n\nfunction unwrapSchema(schema: ZodLike): ZodLike {\n const t = defType(schema);\n if (t === 'optional' || t === 'nullable' || t === 'default') {\n const inner = defInnerType(schema);\n return inner ? unwrapSchema(inner) : schema;\n }\n return schema;\n}\n\nfunction isRequired(schema: ZodLike): boolean {\n const t = defType(schema);\n return t !== 'optional' && t !== 'default';\n}\n\nfunction getDefault(schema: ZodLike): unknown {\n if (defType(schema) === 'default') {\n return schema._def.defaultValue;\n }\n return undefined;\n}\n\nfunction getDescription(schema: ZodLike): string {\n return schema.description ?? '';\n}\n\n/**\n * Maps a Zod schema field to a CliArgType used for help text and parsing.\n */\nfunction resolveCliType(schema: ZodLike): CliArgType {\n const core = unwrapSchema(schema);\n const t = defType(core);\n\n switch (t) {\n case 'boolean':\n return 'boolean';\n case 'number':\n return 'number';\n case 'object':\n case 'record':\n case 'array':\n return 'json';\n case 'union': {\n const opts: readonly ZodLike[] = core._def.options ?? [];\n const hasNonPrimitive = opts.some((o) => {\n const ot = defType(unwrapSchema(o));\n return ot === 'object' || ot === 'array' || ot === 'record';\n });\n return hasNonPrimitive ? 'json' : 'string';\n }\n default:\n return 'string';\n }\n}\n\n/**\n * Returns enum choices if the (unwrapped) schema is a ZodEnum.\n */\nfunction getChoices(schema: ZodLike): string[] | undefined {\n const core = unwrapSchema(schema);\n if (defType(core) === 'enum') {\n return (core as unknown as { options: string[] }).options;\n }\n return undefined;\n}\n\n/**\n * Builds the value placeholder shown in help text, e.g. '<string>', '<json>',\n * '<playwright|extension>'.\n */\nfunction buildValuePlaceholder(argType: CliArgType, choices?: string[]): string {\n if (choices && choices.length > 0) return `<${choices.join('|')}>`;\n switch (argType) {\n case 'boolean':\n return '';\n case 'number':\n return '<number>';\n case 'json':\n return '<json>';\n default:\n return '<string>';\n }\n}\n\n/**\n * Converts a single schema field to a CliArgDefinition.\n */\nfunction fieldToCliArg(key: string, schema: ZodLike): CliArgDefinition {\n const argType = resolveCliType(schema);\n const choices = getChoices(schema);\n const defaultVal = getDefault(schema);\n const desc = getDescription(schema);\n\n return {\n flag: `--${key}`,\n type: argType,\n required: isRequired(schema),\n description: desc,\n default: defaultVal,\n choices,\n typeLabel: describeType(schema),\n };\n}\n\n// ---------------------------------------------------------------------------\n// Help text formatting\n// ---------------------------------------------------------------------------\n\nconst COL_WIDTH = 36;\n\nfunction padEnd(str: string, width: number): string {\n return str.length >= width ? `${str} ` : str.padEnd(width);\n}\n\nfunction renderArg(arg: CliArgDefinition): string {\n const placeholder = buildValuePlaceholder(arg.type, arg.choices);\n const flagPart = placeholder ? `${arg.flag} ${placeholder}` : arg.flag;\n\n const typeAnnotation = arg.type === 'json' ? ` — ${arg.typeLabel}` : '';\n const defaultAnnotation = arg.default !== undefined ? ` [default: ${JSON.stringify(arg.default)}]` : '';\n const description = `${arg.description}${typeAnnotation}${defaultAnnotation}`.trim();\n\n return ` ${padEnd(flagPart, COL_WIDTH)}${description}`;\n}\n\nfunction formatHelp(args: CliArgDefinition[], options: { command?: string; description?: string }): string {\n const lines: string[] = [];\n\n const commandName = options.command ?? '<tool>';\n lines.push(`Usage: ${commandName} [options]`);\n\n if (options.description) {\n lines.push('');\n lines.push(options.description);\n }\n\n const required = args.filter((a) => a.required);\n const optional = args.filter((a) => !a.required);\n\n if (required.length > 0) {\n lines.push('');\n lines.push('Required:');\n for (const arg of required) {\n lines.push(renderArg(arg));\n }\n }\n\n if (optional.length > 0) {\n lines.push('');\n lines.push('Optional:');\n for (const arg of optional) {\n lines.push(renderArg(arg));\n }\n }\n\n return lines.join('\\n');\n}\n\n// ---------------------------------------------------------------------------\n// Public API\n// ---------------------------------------------------------------------------\n\n/**\n * Converts a ZodObject schema to:\n * - `args`: structured CliArgDefinition[] for programmatic use (e.g. parsing)\n * - `help`: formatted help string equivalent to `--help` output\n *\n * Enables AI agents to inspect a tool's expected arguments as CLI flags,\n * then reconstruct a valid call using {@link cliArgsToObject}.\n *\n * @example\n * const { help } = zodToCliArgs(RunSpecToolInputSchema, { command: 'run_spec' });\n * console.log(help);\n * // Usage: run_spec [options]\n * //\n * // Required:\n * // --specPath <string> Absolute path to the spec file\n * //\n * // Optional:\n * // --headless Run in headless mode [default: true]\n * // --env <json> Environment variables — Record<string, string>\n */\nexport function zodToCliArgs(\n schema: z.ZodObject<z.ZodRawShape>,\n options?: { command?: string; description?: string },\n): CliArgsResult {\n const args = Object.entries(schema.shape).map(([key, fieldSchema]) =>\n fieldToCliArg(key, fieldSchema as unknown as ZodLike),\n );\n\n const help = formatHelp(args, options ?? {});\n\n return { args, help };\n}\n","import { z } from 'zod';\nimport { zodToCliArgs } from './zodToCliArgs.js';\n\n// ---------------------------------------------------------------------------\n// Key normalisation\n// ---------------------------------------------------------------------------\n\n/**\n * Converts a CLI flag name (without --) to a camelCase object key.\n * Supports both kebab-case and camelCase input:\n * 'spec-path' → 'specPath'\n * 'specPath' → 'specPath'\n * 'base-url' → 'baseURL' (only uppercases the first letter after -)\n */\nfunction flagToKey(flag: string): string {\n // strip leading -- if present\n const raw = flag.startsWith('--') ? flag.slice(2) : flag;\n // kebab-case → camelCase\n return raw.replace(/-([a-z])/gi, (_, c: string) => c.toUpperCase());\n}\n\n// ---------------------------------------------------------------------------\n// Public API\n// ---------------------------------------------------------------------------\n\n/**\n * Parses a CLI argv array (e.g. process.argv.slice(2)) into a\n * Record<string, unknown> that can be validated by a Zod schema.\n *\n * Uses the schema to determine which flags are booleans (no value expected)\n * and which expect a JSON value (auto-parsed). The result can be passed\n * directly to {@link coerceArgs} or schema.parse().\n *\n * Parsing rules:\n * --flag (boolean in schema) → { flag: true }\n * --no-flag → { flag: false }\n * --key value (json in schema) → { key: JSON.parse(value) }\n * --key value (number in schema) → { key: parseFloat(value) }\n * --key value (string/default) → { key: value }\n * Kebab-case flags are converted to camelCase automatically.\n *\n * @example\n * const obj = cliArgsToObject(\n * ['--specPath', '/tests/foo.spec.ts', '--headless', '--env', '{\"KEY\":\"val\"}'],\n * RunSpecToolInputSchema,\n * );\n * // { specPath: '/tests/foo.spec.ts', headless: true, env: { KEY: 'val' } }\n */\nexport function cliArgsToObject(argv: string[], schema: z.ZodObject<z.ZodRawShape>): Record<string, unknown> {\n const { args: argDefs } = zodToCliArgs(schema);\n\n // Build lookup maps: both camelCase and kebab forms → CliArgDefinition\n const byKey = new Map(argDefs.map((d) => [flagToKey(d.flag), d]));\n // Also support kebab-case lookups (the flag already starts with --)\n const byFlag = new Map(argDefs.map((d) => [d.flag, d]));\n\n const result: Record<string, unknown> = {};\n\n let i = 0;\n while (i < argv.length) {\n const token = argv[i];\n\n if (!token.startsWith('--')) {\n i++;\n continue;\n }\n\n // Handle --no-<flag> negation\n if (token.startsWith('--no-')) {\n const key = flagToKey(token.slice(5)); // strip --no-\n result[key] = false;\n i++;\n continue;\n }\n\n // Support --key=value syntax\n const eqIdx = token.indexOf('=');\n let flagToken: string;\n let inlineValue: string | undefined;\n\n if (eqIdx !== -1) {\n flagToken = token.slice(0, eqIdx);\n inlineValue = token.slice(eqIdx + 1);\n } else {\n flagToken = token;\n inlineValue = undefined;\n }\n\n const key = flagToKey(flagToken);\n const argDef = byKey.get(key) ?? byFlag.get(flagToken);\n\n // Boolean flags: presence alone means true\n if (argDef?.type === 'boolean') {\n result[key] = true;\n i++;\n continue;\n }\n\n // Determine the value: inline (--key=val) or next token\n let rawValue: string | undefined;\n if (inlineValue !== undefined) {\n rawValue = inlineValue;\n i++;\n } else if (i + 1 < argv.length && !argv[i + 1].startsWith('--')) {\n rawValue = argv[i + 1];\n i += 2;\n } else {\n // No value token following — treat as boolean true\n result[key] = true;\n i++;\n continue;\n }\n\n // Parse value based on schema type\n if (argDef?.type === 'json') {\n try {\n result[key] = JSON.parse(rawValue);\n } catch {\n result[key] = rawValue;\n }\n } else if (argDef?.type === 'number') {\n const parsed = Number.parseFloat(rawValue);\n result[key] = Number.isNaN(parsed) ? rawValue : parsed;\n } else {\n result[key] = rawValue;\n }\n }\n\n return result;\n}\n","import { z } from 'zod';\n\n// ---------------------------------------------------------------------------\n// Internal helpers\n// ---------------------------------------------------------------------------\n\ntype JsonSchemaNode = Record<string, unknown>;\n\n/**\n * Convert a single JSON Schema property node to a Zod type.\n * Handles: string, number, integer, boolean, null, array, object,\n * anyOf/oneOf, enum, and array-of-types (e.g. [\"string\",\"null\"]).\n */\nfunction propertyToZod(node: unknown): z.ZodTypeAny {\n if (!node || typeof node !== 'object' || Array.isArray(node)) return z.unknown();\n const n = node as JsonSchemaNode;\n\n // anyOf / oneOf → union\n const variants = (n.anyOf ?? n.oneOf) as unknown[] | undefined;\n if (Array.isArray(variants) && variants.length > 0) {\n const members = variants.map(propertyToZod);\n if (members.length === 1) return members[0];\n return z.union([members[0], members[1], ...members.slice(2)] as [z.ZodTypeAny, z.ZodTypeAny, ...z.ZodTypeAny[]]);\n }\n\n // enum\n if (Array.isArray(n.enum) && n.enum.every((v) => typeof v === 'string')) {\n const [first, second, ...rest] = n.enum as string[];\n if (first === undefined) return z.unknown();\n if (second === undefined) return z.literal(first);\n return z.enum([first, second, ...rest]);\n }\n\n const type = n.type;\n\n // Array-of-types: [\"string\", \"null\"] → optional string\n if (Array.isArray(type)) {\n const nonNull = type.filter((t) => t !== 'null') as string[];\n const nullable = type.includes('null');\n if (nonNull.length === 0) return nullable ? z.null() : z.unknown();\n const inner =\n nonNull.length === 1\n ? propertyToZod({ ...n, type: nonNull[0] })\n : z.union(\n nonNull.map((t) => propertyToZod({ ...n, type: t })) as [z.ZodTypeAny, z.ZodTypeAny, ...z.ZodTypeAny[]],\n );\n return nullable ? z.union([inner, z.null()]) : inner;\n }\n\n if (type === 'string') return z.string();\n if (type === 'number' || type === 'integer') return z.number();\n if (type === 'boolean') return z.boolean();\n if (type === 'null') return z.null();\n\n if (type === 'array') {\n const items = n.items ? propertyToZod(n.items) : z.unknown();\n return z.array(items);\n }\n\n if (type === 'object') {\n if (n.properties && typeof n.properties === 'object' && !Array.isArray(n.properties)) {\n return jsonSchemaToZod(n);\n }\n return z.record(z.string(), z.unknown());\n }\n\n return z.unknown();\n}\n\n// ---------------------------------------------------------------------------\n// Public API\n// ---------------------------------------------------------------------------\n\n/**\n * Convert a JSON Schema object definition to a Zod object schema.\n *\n * Handles `properties`, `required`, `anyOf`/`oneOf`, `enum`, and the\n * common scalar types. Fields not listed in `required` are made optional.\n * Unknown/unsupported nodes map to `z.unknown()`.\n *\n * This is intentionally non-exhaustive: the goal is accurate type\n * classification for coercion (primitive vs non-primitive), not strict\n * schema validation.\n *\n * @example\n * const schema = jsonSchemaToZod({\n * type: 'object',\n * properties: {\n * env: { type: 'object' },\n * headless: { type: 'boolean' },\n * },\n * required: ['env'],\n * });\n * // schema.shape.env → ZodRecord (non-primitive → will be JSON.parsed if string)\n * // schema.shape.headless → ZodOptional<ZodBoolean>\n */\nexport function jsonSchemaToZod(schema: Record<string, unknown>): z.ZodObject<z.ZodRawShape> {\n const properties = schema.properties as Record<string, unknown> | undefined;\n const required = new Set<string>(Array.isArray(schema.required) ? (schema.required as string[]) : []);\n\n if (!properties) return z.object({});\n\n const shape: Record<string, z.ZodTypeAny> = {};\n for (const [key, prop] of Object.entries(properties)) {\n const zodType = propertyToZod(prop);\n shape[key] = required.has(key) ? zodType : zodType.optional();\n }\n\n return z.object(shape);\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.mjs","names":["defType","defType","defInnerType","isRequired"],"sources":["../src/utils/coerceArgs.ts","../src/utils/formatZodError.ts","../src/utils/zodToCliArgs.ts","../src/utils/cliArgsToObject.ts","../src/utils/jsonSchemaToZod.ts"],"sourcesContent":["import { z } from 'zod';\n\n// ---------------------------------------------------------------------------\n// Internal helpers — Zod v4 compatible\n// ---------------------------------------------------------------------------\n\n// Zod v4 schema shapes expose $ZodType internally; use a structural interface\n// to avoid the public ZodType vs $ZodType mismatch.\ninterface ZodLike {\n _def: { type?: string; innerType?: ZodLike; options?: ZodLike[] };\n}\n\nfunction defType(schema: ZodLike): string {\n return schema._def.type ?? '';\n}\n\nfunction unwrapZodLike(schema: ZodLike): ZodLike {\n const t = defType(schema);\n if (t === 'optional' || t === 'nullable' || t === 'default') {\n const inner = schema._def.innerType;\n return inner ? unwrapZodLike(inner) : schema;\n }\n return schema;\n}\n\nfunction isNonPrimitive(schema: ZodLike): boolean {\n const core = unwrapZodLike(schema);\n const t = defType(core);\n if (t === 'object' || t === 'array' || t === 'record') return true;\n if (t === 'union') {\n return (core._def.options ?? []).some(isNonPrimitive);\n }\n return false;\n}\n\n// ---------------------------------------------------------------------------\n// Public API\n// ---------------------------------------------------------------------------\n\n/**\n * Walks a ZodObject's shape and, for any field that expects a non-primitive\n * type (object, array, record, or union containing one), attempts to\n * JSON.parse string values. Leaves the value unchanged if:\n * - it is not a string\n * - the schema expects a primitive\n * - the string is not valid JSON\n *\n * This handles the common Claude Code behaviour of stringifying nested args\n * (e.g. env: '{\"KEY\":\"val\"}' instead of env: { KEY: 'val' }).\n */\nexport function coerceArgs(args: Record<string, unknown>, schema: z.ZodObject<z.ZodRawShape>): Record<string, unknown> {\n const result = { ...args };\n\n for (const [key, rawSchema] of Object.entries(schema.shape)) {\n const value = result[key];\n if (typeof value !== 'string') continue;\n if (!isNonPrimitive(rawSchema as unknown as ZodLike)) continue;\n\n try {\n result[key] = JSON.parse(value);\n } catch {\n // keep as string — not valid JSON\n }\n }\n\n return result;\n}\n","import { z } from 'zod';\n\n// ---------------------------------------------------------------------------\n// Internal schema introspection — Zod v4 compatible\n// ---------------------------------------------------------------------------\n\n// Structural interface compatible with both $ZodType (internal) and ZodType (public)\ninterface ZodLike {\n _def: {\n type?: string;\n innerType?: ZodLike;\n element?: ZodLike;\n valueType?: ZodLike;\n options?: readonly ZodLike[];\n value?: unknown;\n };\n description?: string;\n}\n\nfunction defType(schema: ZodLike): string {\n return schema._def.type ?? '';\n}\n\nfunction defInnerType(schema: ZodLike): ZodLike | undefined {\n return schema._def.innerType;\n}\n\nfunction isRequired(schema: ZodLike): boolean {\n const t = defType(schema);\n return t !== 'optional' && t !== 'default';\n}\n\n/**\n * Produces a concise human-readable type label for a Zod schema.\n * Examples: 'string', 'string[]', 'Record<string, string>', 'enum [a, b]'\n */\nexport function describeType(schema: ZodLike): string {\n const t = defType(schema);\n switch (t) {\n case 'string':\n return 'string';\n case 'number':\n return 'number';\n case 'boolean':\n return 'boolean';\n case 'bigint':\n return 'bigint';\n case 'null':\n return 'null';\n case 'undefined':\n return 'undefined';\n case 'any':\n return 'any';\n case 'unknown':\n return 'unknown';\n case 'literal':\n return JSON.stringify(schema._def.value);\n case 'enum': {\n // ZodEnum in v4 exposes .options as a getter\n const opts = (schema as unknown as { options: string[] }).options ?? [];\n return `enum [${opts.join(', ')}]`;\n }\n case 'array': {\n const el = schema._def.element;\n return el ? `${describeType(el)}[]` : 'unknown[]';\n }\n case 'record': {\n const valType = schema._def.valueType;\n return valType ? `Record<string, ${describeType(valType)}>` : 'Record<string, unknown>';\n }\n case 'object':\n return 'object';\n case 'optional':\n case 'nullable':\n case 'default': {\n const inner = defInnerType(schema);\n return inner ? describeType(inner) : 'unknown';\n }\n case 'union': {\n const opts = schema._def.options ?? [];\n return opts.map(describeType).join(' | ');\n }\n default:\n return 'unknown';\n }\n}\n\n// ---------------------------------------------------------------------------\n// Issue formatting — Zod v4 issue shapes\n// ---------------------------------------------------------------------------\n\n// Zod v4 uses 'invalid_value' (not 'invalid_enum_value') for enum violations.\n// Use string cast on issue.code to avoid ZodIssueCode constraint errors.\n\ninterface InvalidTypeIssueV4 {\n code: string;\n expected: string;\n message: string;\n path: (string | number)[];\n}\n\ninterface InvalidValueIssueV4 {\n code: string;\n values: (string | number)[];\n message: string;\n path: (string | number)[];\n}\n\ninterface TooSmallIssueV4 {\n code: string;\n minimum: number | bigint;\n inclusive: boolean;\n message: string;\n path: (string | number)[];\n}\n\ninterface TooBigIssueV4 {\n code: string;\n maximum: number | bigint;\n inclusive: boolean;\n message: string;\n path: (string | number)[];\n}\n\ninterface UnrecognizedKeysIssueV4 {\n code: string;\n keys: string[];\n message: string;\n path: (string | number)[];\n}\n\nfunction extractReceived(message: string): string | undefined {\n return message.match(/received (\\w+)(?:\\s|$)/)?.[1];\n}\n\nfunction formatIssueMessage(issue: z.ZodIssue): string {\n const code = issue.code as string;\n switch (code) {\n case 'invalid_type': {\n const i = issue as unknown as InvalidTypeIssueV4;\n const received = extractReceived(i.message);\n if (received === 'undefined') return 'Required field is missing';\n return i.message;\n }\n // Zod v4 uses 'invalid_value' for enum violations\n case 'invalid_value': {\n const i = issue as unknown as InvalidValueIssueV4;\n return `Invalid value — must be one of: ${i.values.join(', ')}`;\n }\n case 'too_small': {\n const i = issue as unknown as TooSmallIssueV4;\n return `Value too small — minimum is ${String(i.minimum)}${i.inclusive ? ' (inclusive)' : ' (exclusive)'}`;\n }\n case 'too_big': {\n const i = issue as unknown as TooBigIssueV4;\n return `Value too large — maximum is ${String(i.maximum)}${i.inclusive ? ' (inclusive)' : ' (exclusive)'}`;\n }\n case 'unrecognized_keys': {\n const i = issue as unknown as UnrecognizedKeysIssueV4;\n return `Unrecognized keys: ${i.keys.join(', ')}`;\n }\n default:\n return issue.message;\n }\n}\n\nfunction getActionableHint(issue: z.ZodIssue, fieldPath: string, fieldSchema: ZodLike | undefined): string | undefined {\n const flag = `--${fieldPath}`;\n const code = issue.code as string;\n\n switch (code) {\n case 'invalid_type': {\n const i = issue as unknown as InvalidTypeIssueV4;\n const received = extractReceived(i.message);\n\n if (received === 'undefined') {\n const typeLabel = fieldSchema ? describeType(fieldSchema) : 'value';\n return `Provide: ${flag} <${typeLabel}>`;\n }\n\n if (received === 'string' && (i.expected === 'record' || i.expected === 'array' || i.expected === 'object')) {\n return `Received a JSON string instead of ${i.expected}.\\n → The coercion layer should handle this automatically.\\n → CLI usage: ${flag} '<json ${i.expected}>'`;\n }\n\n return undefined;\n }\n\n case 'invalid_value': {\n const i = issue as unknown as InvalidValueIssueV4;\n const example = i.values[0];\n return `Use: ${flag} ${String(example)}`;\n }\n\n default:\n return undefined;\n }\n}\n\nfunction getFieldSchema(pathSegments: string[], schema: z.ZodObject<z.ZodRawShape>): ZodLike | undefined {\n if (pathSegments.length === 0) return undefined;\n return schema.shape[pathSegments[0]] as unknown as ZodLike | undefined;\n}\n\n// ---------------------------------------------------------------------------\n// Public API\n// ---------------------------------------------------------------------------\n\n/**\n * Converts a ZodError into a multi-line string optimized for AI agents.\n *\n * Each field with errors shows:\n * - field name, whether it is required/optional, and its expected type\n * - a concise description of what went wrong\n * - a concrete actionable hint (e.g. CLI flag usage)\n *\n * Detecting stringified objects: when the error says \"expected record/array,\n * received string\", it calls out the common Claude Code serialisation issue\n * and explains that the coercion layer should handle it automatically.\n *\n * @example\n * try {\n * schema.parse(args);\n * } catch (err) {\n * if (err instanceof z.ZodError) {\n * console.error(formatZodError(err, { schemaName: 'run_spec', schema }));\n * }\n * }\n */\nexport function formatZodError(\n error: z.ZodError,\n options?: { schemaName?: string; schema?: z.ZodObject<z.ZodRawShape> },\n): string {\n const { schemaName, schema } = options ?? {};\n\n // Group issues by dotted path\n const byPath = new Map<string, z.ZodIssue[]>();\n for (const issue of error.issues) {\n const path = issue.path.length > 0 ? issue.path.map(String).join('.') : '(root)';\n const existing = byPath.get(path) ?? [];\n existing.push(issue);\n byPath.set(path, existing);\n }\n\n const header = schemaName ? `Validation failed for \"${schemaName}\":` : 'Validation failed:';\n const lines: string[] = [header];\n\n for (const [path, issues] of byPath) {\n lines.push('');\n\n const fieldSchema = schema ? getFieldSchema(path.split('.'), schema) : undefined;\n const required = fieldSchema\n ? isRequired(fieldSchema)\n : issues.some((i) => {\n if ((i.code as string) !== 'invalid_type') return false;\n const msg = (i as unknown as { message: string }).message;\n return extractReceived(msg) === 'undefined';\n });\n\n const typeDesc = fieldSchema ? describeType(fieldSchema) : '';\n const meta = `(${required ? 'required' : 'optional'})${typeDesc ? ` — ${typeDesc}` : ''}`;\n\n lines.push(` • ${path} ${meta}`);\n\n for (const issue of issues) {\n lines.push(` ✗ ${formatIssueMessage(issue)}`);\n const hint = getActionableHint(issue, path, fieldSchema);\n if (hint) {\n lines.push(` → ${hint}`);\n }\n }\n }\n\n return lines.join('\\n');\n}\n","import { z } from 'zod';\nimport type { CliArgDefinition, CliArgType, CliArgsResult } from '../types/index.js';\nimport { describeType } from './formatZodError.js';\n\n// ---------------------------------------------------------------------------\n// Internal helpers — Zod v4 compatible\n// ---------------------------------------------------------------------------\n\n// Structural interface compatible with both $ZodType (internal) and ZodType (public)\ninterface ZodLike {\n _def: { type?: string; innerType?: ZodLike; defaultValue?: unknown; options?: readonly ZodLike[] };\n description?: string;\n}\n\nfunction defType(schema: ZodLike): string {\n return schema._def.type ?? '';\n}\n\nfunction defInnerType(schema: ZodLike): ZodLike | undefined {\n return schema._def.innerType;\n}\n\nfunction unwrapSchema(schema: ZodLike): ZodLike {\n const t = defType(schema);\n if (t === 'optional' || t === 'nullable' || t === 'default') {\n const inner = defInnerType(schema);\n return inner ? unwrapSchema(inner) : schema;\n }\n return schema;\n}\n\nfunction isRequired(schema: ZodLike): boolean {\n const t = defType(schema);\n return t !== 'optional' && t !== 'default';\n}\n\nfunction getDefault(schema: ZodLike): unknown {\n if (defType(schema) === 'default') {\n return schema._def.defaultValue;\n }\n return undefined;\n}\n\nfunction getDescription(schema: ZodLike): string {\n return schema.description ?? '';\n}\n\n/**\n * Maps a Zod schema field to a CliArgType used for help text and parsing.\n */\nfunction resolveCliType(schema: ZodLike): CliArgType {\n const core = unwrapSchema(schema);\n const t = defType(core);\n\n switch (t) {\n case 'boolean':\n return 'boolean';\n case 'number':\n return 'number';\n case 'object':\n case 'record':\n case 'array':\n return 'json';\n case 'union': {\n const opts: readonly ZodLike[] = core._def.options ?? [];\n const hasNonPrimitive = opts.some((o) => {\n const ot = defType(unwrapSchema(o));\n return ot === 'object' || ot === 'array' || ot === 'record';\n });\n return hasNonPrimitive ? 'json' : 'string';\n }\n default:\n return 'string';\n }\n}\n\n/**\n * Returns enum choices if the (unwrapped) schema is a ZodEnum.\n */\nfunction getChoices(schema: ZodLike): string[] | undefined {\n const core = unwrapSchema(schema);\n if (defType(core) === 'enum') {\n return (core as unknown as { options: string[] }).options;\n }\n return undefined;\n}\n\n/**\n * Builds the value placeholder shown in help text, e.g. '<string>', '<json>',\n * '<playwright|extension>'.\n */\nfunction buildValuePlaceholder(argType: CliArgType, choices?: string[]): string {\n if (choices && choices.length > 0) return `<${choices.join('|')}>`;\n switch (argType) {\n case 'boolean':\n return '';\n case 'number':\n return '<number>';\n case 'json':\n return '<json>';\n default:\n return '<string>';\n }\n}\n\n/**\n * Converts a single schema field to a CliArgDefinition.\n */\nfunction fieldToCliArg(key: string, schema: ZodLike): CliArgDefinition {\n const argType = resolveCliType(schema);\n const choices = getChoices(schema);\n const defaultVal = getDefault(schema);\n const desc = getDescription(schema);\n\n return {\n flag: `--${key}`,\n type: argType,\n required: isRequired(schema),\n description: desc,\n default: defaultVal,\n choices,\n typeLabel: describeType(schema),\n };\n}\n\n// ---------------------------------------------------------------------------\n// Help text formatting\n// ---------------------------------------------------------------------------\n\nconst COL_WIDTH = 36;\n\nfunction padEnd(str: string, width: number): string {\n return str.length >= width ? `${str} ` : str.padEnd(width);\n}\n\nfunction renderArg(arg: CliArgDefinition): string {\n const placeholder = buildValuePlaceholder(arg.type, arg.choices);\n const flagPart = placeholder ? `${arg.flag} ${placeholder}` : arg.flag;\n\n const typeAnnotation = arg.type === 'json' ? ` — ${arg.typeLabel}` : '';\n const defaultAnnotation = arg.default !== undefined ? ` [default: ${JSON.stringify(arg.default)}]` : '';\n const description = `${arg.description}${typeAnnotation}${defaultAnnotation}`.trim();\n\n return ` ${padEnd(flagPart, COL_WIDTH)}${description}`;\n}\n\nfunction formatHelp(args: CliArgDefinition[], options: { command?: string; description?: string }): string {\n const lines: string[] = [];\n\n const commandName = options.command ?? '<tool>';\n lines.push(`Usage: ${commandName} [options]`);\n\n if (options.description) {\n lines.push('');\n lines.push(options.description);\n }\n\n const required = args.filter((a) => a.required);\n const optional = args.filter((a) => !a.required);\n\n if (required.length > 0) {\n lines.push('');\n lines.push('Required:');\n for (const arg of required) {\n lines.push(renderArg(arg));\n }\n }\n\n if (optional.length > 0) {\n lines.push('');\n lines.push('Optional:');\n for (const arg of optional) {\n lines.push(renderArg(arg));\n }\n }\n\n return lines.join('\\n');\n}\n\n// ---------------------------------------------------------------------------\n// Public API\n// ---------------------------------------------------------------------------\n\n/**\n * Converts a ZodObject schema to:\n * - `args`: structured CliArgDefinition[] for programmatic use (e.g. parsing)\n * - `help`: formatted help string equivalent to `--help` output\n *\n * Enables AI agents to inspect a tool's expected arguments as CLI flags,\n * then reconstruct a valid call using {@link cliArgsToObject}.\n *\n * @example\n * const { help } = zodToCliArgs(RunSpecToolInputSchema, { command: 'run_spec' });\n * console.log(help);\n * // Usage: run_spec [options]\n * //\n * // Required:\n * // --specPath <string> Absolute path to the spec file\n * //\n * // Optional:\n * // --headless Run in headless mode [default: true]\n * // --env <json> Environment variables — Record<string, string>\n */\nexport function zodToCliArgs(\n schema: z.ZodObject<z.ZodRawShape>,\n options?: { command?: string; description?: string },\n): CliArgsResult {\n const args = Object.entries(schema.shape).map(([key, fieldSchema]) =>\n fieldToCliArg(key, fieldSchema as unknown as ZodLike),\n );\n\n const help = formatHelp(args, options ?? {});\n\n return { args, help };\n}\n","import { z } from 'zod';\nimport { zodToCliArgs } from './zodToCliArgs.js';\n\n// ---------------------------------------------------------------------------\n// Key normalisation\n// ---------------------------------------------------------------------------\n\n/**\n * Converts a CLI flag name (without --) to a camelCase object key.\n * Supports both kebab-case and camelCase input:\n * 'spec-path' → 'specPath'\n * 'specPath' → 'specPath'\n * 'base-url' → 'baseURL' (only uppercases the first letter after -)\n */\nfunction flagToKey(flag: string): string {\n // strip leading -- if present\n const raw = flag.startsWith('--') ? flag.slice(2) : flag;\n // kebab-case → camelCase\n return raw.replace(/-([a-z])/gi, (_, c: string) => c.toUpperCase());\n}\n\n// ---------------------------------------------------------------------------\n// Public API\n// ---------------------------------------------------------------------------\n\n/**\n * Parses a CLI argv array (e.g. process.argv.slice(2)) into a\n * Record<string, unknown> that can be validated by a Zod schema.\n *\n * Uses the schema to determine which flags are booleans (no value expected)\n * and which expect a JSON value (auto-parsed). The result can be passed\n * directly to {@link coerceArgs} or schema.parse().\n *\n * Parsing rules:\n * --flag (boolean in schema) → { flag: true }\n * --no-flag → { flag: false }\n * --key value (json in schema) → { key: JSON.parse(value) }\n * --key value (number in schema) → { key: parseFloat(value) }\n * --key value (string/default) → { key: value }\n * Kebab-case flags are converted to camelCase automatically.\n *\n * @example\n * const obj = cliArgsToObject(\n * ['--specPath', '/tests/foo.spec.ts', '--headless', '--env', '{\"KEY\":\"val\"}'],\n * RunSpecToolInputSchema,\n * );\n * // { specPath: '/tests/foo.spec.ts', headless: true, env: { KEY: 'val' } }\n */\nexport function cliArgsToObject(argv: string[], schema: z.ZodObject<z.ZodRawShape>): Record<string, unknown> {\n const { args: argDefs } = zodToCliArgs(schema);\n\n // Build lookup maps: both camelCase and kebab forms → CliArgDefinition\n const byKey = new Map(argDefs.map((d) => [flagToKey(d.flag), d]));\n // Also support kebab-case lookups (the flag already starts with --)\n const byFlag = new Map(argDefs.map((d) => [d.flag, d]));\n\n const result: Record<string, unknown> = {};\n\n let i = 0;\n while (i < argv.length) {\n const token = argv[i];\n\n if (!token.startsWith('--')) {\n i++;\n continue;\n }\n\n // Handle --no-<flag> negation\n if (token.startsWith('--no-')) {\n const key = flagToKey(token.slice(5)); // strip --no-\n result[key] = false;\n i++;\n continue;\n }\n\n // Support --key=value syntax\n const eqIdx = token.indexOf('=');\n let flagToken: string;\n let inlineValue: string | undefined;\n\n if (eqIdx !== -1) {\n flagToken = token.slice(0, eqIdx);\n inlineValue = token.slice(eqIdx + 1);\n } else {\n flagToken = token;\n inlineValue = undefined;\n }\n\n const key = flagToKey(flagToken);\n const argDef = byKey.get(key) ?? byFlag.get(flagToken);\n\n // Boolean flags: presence alone means true\n if (argDef?.type === 'boolean') {\n result[key] = true;\n i++;\n continue;\n }\n\n // Determine the value: inline (--key=val) or next token\n let rawValue: string | undefined;\n if (inlineValue !== undefined) {\n rawValue = inlineValue;\n i++;\n } else if (i + 1 < argv.length && !argv[i + 1].startsWith('--')) {\n rawValue = argv[i + 1];\n i += 2;\n } else {\n // No value token following — treat as boolean true\n result[key] = true;\n i++;\n continue;\n }\n\n // Parse value based on schema type\n if (argDef?.type === 'json') {\n try {\n result[key] = JSON.parse(rawValue);\n } catch {\n result[key] = rawValue;\n }\n } else if (argDef?.type === 'number') {\n const parsed = Number.parseFloat(rawValue);\n result[key] = Number.isNaN(parsed) ? rawValue : parsed;\n } else {\n result[key] = rawValue;\n }\n }\n\n return result;\n}\n","import { z } from 'zod';\n\n// ---------------------------------------------------------------------------\n// Internal helpers\n// ---------------------------------------------------------------------------\n\ntype JsonSchemaNode = Record<string, unknown>;\n\n/**\n * Convert a single JSON Schema property node to a Zod type.\n * Handles: string, number, integer, boolean, null, array, object,\n * anyOf/oneOf, enum, and array-of-types (e.g. [\"string\",\"null\"]).\n */\nfunction propertyToZod(node: unknown): z.ZodTypeAny {\n if (!node || typeof node !== 'object' || Array.isArray(node)) return z.unknown();\n const n = node as JsonSchemaNode;\n\n // anyOf / oneOf → union\n const variants = (n.anyOf ?? n.oneOf) as unknown[] | undefined;\n if (Array.isArray(variants) && variants.length > 0) {\n const members = variants.map(propertyToZod);\n if (members.length === 1) return members[0];\n return z.union([members[0], members[1], ...members.slice(2)] as [z.ZodTypeAny, z.ZodTypeAny, ...z.ZodTypeAny[]]);\n }\n\n // enum\n if (Array.isArray(n.enum) && n.enum.every((v) => typeof v === 'string')) {\n const [first, second, ...rest] = n.enum as string[];\n if (first === undefined) return z.unknown();\n if (second === undefined) return z.literal(first);\n return z.enum([first, second, ...rest]);\n }\n\n const type = n.type;\n\n // Array-of-types: [\"string\", \"null\"] → optional string\n if (Array.isArray(type)) {\n const nonNull = type.filter((t) => t !== 'null') as string[];\n const nullable = type.includes('null');\n if (nonNull.length === 0) return nullable ? z.null() : z.unknown();\n const inner =\n nonNull.length === 1\n ? propertyToZod({ ...n, type: nonNull[0] })\n : z.union(\n nonNull.map((t) => propertyToZod({ ...n, type: t })) as [z.ZodTypeAny, z.ZodTypeAny, ...z.ZodTypeAny[]],\n );\n return nullable ? z.union([inner, z.null()]) : inner;\n }\n\n if (type === 'string') return z.string();\n if (type === 'number' || type === 'integer') return z.number();\n if (type === 'boolean') return z.boolean();\n if (type === 'null') return z.null();\n\n if (type === 'array') {\n const items = n.items ? propertyToZod(n.items) : z.unknown();\n return z.array(items);\n }\n\n if (type === 'object') {\n if (n.properties && typeof n.properties === 'object' && !Array.isArray(n.properties)) {\n return jsonSchemaToZod(n);\n }\n return z.record(z.string(), z.unknown());\n }\n\n return z.unknown();\n}\n\n// ---------------------------------------------------------------------------\n// Public API\n// ---------------------------------------------------------------------------\n\n/**\n * Convert a JSON Schema object definition to a Zod object schema.\n *\n * Handles `properties`, `required`, `anyOf`/`oneOf`, `enum`, and the\n * common scalar types. Fields not listed in `required` are made optional.\n * Unknown/unsupported nodes map to `z.unknown()`.\n *\n * This is intentionally non-exhaustive: the goal is accurate type\n * classification for coercion (primitive vs non-primitive), not strict\n * schema validation.\n *\n * @example\n * const schema = jsonSchemaToZod({\n * type: 'object',\n * properties: {\n * env: { type: 'object' },\n * headless: { type: 'boolean' },\n * },\n * required: ['env'],\n * });\n * // schema.shape.env → ZodRecord (non-primitive → will be JSON.parsed if string)\n * // schema.shape.headless → ZodOptional<ZodBoolean>\n */\nexport function jsonSchemaToZod(schema: Record<string, unknown>): z.ZodObject<z.ZodRawShape> {\n const properties = schema.properties as Record<string, unknown> | undefined;\n const required = new Set<string>(Array.isArray(schema.required) ? (schema.required as string[]) : []);\n\n if (!properties) return z.object({});\n\n const shape: Record<string, z.ZodTypeAny> = {};\n for (const [key, prop] of Object.entries(properties)) {\n const zodType = propertyToZod(prop);\n shape[key] = required.has(key) ? zodType : zodType.optional();\n }\n\n return z.object(shape);\n}\n"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@agimon-ai/foundation-validator",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.0",
|
|
4
4
|
"description": "Zod-based validation utilities: schema coercion, AI-readable error formatting, and CLI arg conversion",
|
|
5
5
|
"main": "./dist/index.cjs",
|
|
6
6
|
"module": "./dist/index.mjs",
|
|
7
|
-
"types": "./dist/index.d.
|
|
7
|
+
"types": "./dist/index.d.cts",
|
|
8
8
|
"sideEffects": false,
|
|
9
9
|
"publishConfig": {
|
|
10
10
|
"access": "public"
|
|
@@ -13,21 +13,20 @@
|
|
|
13
13
|
"zod": "4.3.6"
|
|
14
14
|
},
|
|
15
15
|
"devDependencies": {
|
|
16
|
-
"@types/node": "
|
|
17
|
-
"tsdown": "0.
|
|
18
|
-
"typescript": "
|
|
19
|
-
"vitest": "4.
|
|
16
|
+
"@types/node": "25.6.0",
|
|
17
|
+
"tsdown": "0.21.7",
|
|
18
|
+
"typescript": "6.0.2",
|
|
19
|
+
"vitest": "4.1.4"
|
|
20
20
|
},
|
|
21
21
|
"author": "Vuong Ngo",
|
|
22
22
|
"license": "BUSL-1.1",
|
|
23
23
|
"type": "module",
|
|
24
24
|
"exports": {
|
|
25
25
|
".": {
|
|
26
|
-
"types": "./dist/index.d.mts",
|
|
27
26
|
"import": "./dist/index.mjs",
|
|
28
27
|
"require": "./dist/index.cjs"
|
|
29
28
|
},
|
|
30
|
-
"
|
|
29
|
+
"./package.json": "./package.json"
|
|
31
30
|
},
|
|
32
31
|
"files": [
|
|
33
32
|
"dist",
|