import { z } from 'zod' /** * Shared Zod schemas used by multiple MCP tools. Keep DRY — if a shape is * referenced by more than one tool, define it here. */ /** A node identifier — non-empty string. The core uses `${prefix}_${nanoid}`. */ export const NodeIdSchema = z.string().min(1) /** * 2D point as [x, z] (floor plane). Use array length constraints instead of * `z.tuple()` so MCP hosts that only accept JSON Schema's common `items` shape * can register the tools. */ export const Vec2Schema = z.array(z.number()).min(2).max(2) /** 3D point as [x, y, z]. */ export const Vec3Schema = z.array(z.number()).min(3).max(3) /** * A single patch operation. Union of create / update / delete. * * For `create`, the node object must include `type` so Zod can discriminate at * the bridge layer — we accept a plain object here and let the bridge's Zod * re-parse catch structural issues. For `update`, `data` is a partial merge. */ export const CreatePatchSchema = z.object({ op: z.literal('create'), node: z.record(z.string(), z.unknown()), parentId: NodeIdSchema.optional(), }) export const UpdatePatchSchema = z.object({ op: z.literal('update'), id: NodeIdSchema, data: z.record(z.string(), z.unknown()), }) export const DeletePatchSchema = z.object({ op: z.literal('delete'), id: NodeIdSchema, cascade: z.boolean().optional(), }) export const PatchSchema = z.discriminatedUnion('op', [ CreatePatchSchema, UpdatePatchSchema, DeletePatchSchema, ]) export type Patch = z.infer