import type { TreeStructure } from '@/types' export interface TreeMetadata { name?: string description?: string category?: string tags?: string[] } /** * Lightweight frontend serializer for instant preview when switching Form→Code. * The backend remains authoritative for actual saves. */ export function treeStructureToMarkdownPreview( structure: TreeStructure, metadata?: TreeMetadata, ): string { const blocks: string[] = [] if (metadata) { const fm = ['---'] if (metadata.name) fm.push(`name: ${metadata.name}`) if (metadata.description) fm.push(`description: ${metadata.description}`) if (metadata.category) fm.push(`category: ${metadata.category}`) if (metadata.tags?.length) fm.push(`tags: [${metadata.tags.join(', ')}]`) fm.push('---') blocks.push(fm.join('\n')) } serializeNode(structure, null, blocks) return blocks.join('\n\n') + '\n' } function serializeNode( node: TreeStructure, parentId: string | null, blocks: string[], ): void { const fm = ['---', `id: ${node.id}`, `type: ${node.type}`] if (parentId !== null) fm.push(`parent: ${parentId}`) fm.push('---') const body: string[] = [] if (node.type === 'decision') { if (node.question) { body.push(`# ${node.question}`, '') } if (node.help_text) { for (const line of node.help_text.split('\n')) { body.push(`> ${line}`) } body.push('') } if (node.options) { node.options.forEach((opt, i) => { const letter = String.fromCharCode(65 + i) if (opt.next_node_id) { body.push(`- [${letter}] ${opt.label} → @${opt.next_node_id}`) } else { body.push(`- [${letter}] ${opt.label}`) } }) } } else if (node.type === 'action') { if (node.title) body.push(`## ${node.title}`, '') if (node.description) body.push(node.description, '') if (node.commands?.length) { body.push('```commands') node.commands.forEach(cmd => body.push(cmd)) body.push('```', '') } if (node.expected_outcome) body.push(`**Expected:** ${node.expected_outcome}`, '') if (node.next_node_id) body.push(`→ @${node.next_node_id}`) } else if (node.type === 'solution') { if (node.title) body.push(`## ${node.title}`, '') if (node.description) body.push(node.description, '') if (node.resolution_steps?.length) { node.resolution_steps.forEach((step, i) => body.push(`${i + 1}. ${step}`)) } } blocks.push(fm.join('\n') + '\n' + body.join('\n')) if (node.children) { for (const child of node.children) { serializeNode(child, node.id, blocks) } } }