import { SitesmithTarget } from '../state/SitesmithContext'; /** * Build a Sitesmith target descriptor from a Craft.js node id. The returned * `treeJson` is a flat node-map (compatible with the editor's serialized * format) for just the selected subtree; the server includes it in the AI * prompt so the model has the exact current shape of the block to modify. */ export function buildSitesmithTarget(query: any, nodeId: string): SitesmithTarget | null { if (!nodeId || nodeId === 'ROOT') return null; try { const node = query.node(nodeId).get(); const displayName = node?.data?.displayName || node?.data?.type?.resolvedName || 'Block'; // Use Craft.js' own subtree serializer — toNodeTree gives a flat map keyed // by node id, identical to what `actions.deserialize()` consumes. const subtree = query.node(nodeId).toNodeTree(); const serializedMap: Record = {}; for (const [id, n] of Object.entries(subtree.nodes ?? {}) as [string, any][]) { serializedMap[id] = { type: n.data.type, props: n.data.props, displayName: n.data.displayName, isCanvas: n.data.isCanvas ?? false, parent: n.data.parent, nodes: n.data.nodes ?? [], linkedNodes: n.data.linkedNodes ?? {}, hidden: n.data.hidden ?? false, custom: n.data.custom ?? {}, }; } return { nodeId, displayName, treeJson: JSON.stringify({ root: subtree.rootNodeId, nodes: serializedMap }), }; } catch (e) { console.warn('buildSitesmithTarget failed:', e); return null; } }