import { readFileSync, writeFileSync } from 'node:fs'; import { join } from 'node:path'; const root = '/Users/sylvawong/oneos1.2'; const prdPath = join(root, 'src/resources/vehicle-h2-fee-ledger/PRD.md'); const prd = readFileSync(prdPath, 'utf8'); const specPrdPath = join(root, 'src/prototypes/vehicle-h2-fee-ledger/.spec/PRD.md'); writeFileSync(specPrdPath, prd, 'utf8'); const resourcesAlias = join(root, 'src/resources/vehicle-h2-fee-ledger/车辆氢费明细-需求文档.md'); writeFileSync(resourcesAlias, prd, 'utf8'); const runtimePath = join(root, '.local/extract-annotation-source/output.json'); const runtime = JSON.parse(readFileSync(runtimePath, 'utf8')); const runtimeSource = runtime.source; const annPath = join(root, 'src/prototypes/vehicle-h2-fee-ledger/annotation-source.json'); const ann = JSON.parse(readFileSync(annPath, 'utf8')); function findChild(nodes, id) { for (const n of nodes || []) { if (n.id === id) return n; if (n.children) { const found = findChild(n.children, id); if (found) return found; } } return null; } const docRoot = ann.directory.nodes[0]; const prdNode = findChild(docRoot.children, 'vh2-doc-prd'); if (prdNode) { prdNode.markdown = prd; prdNode.markdownPath = '.spec/PRD.md'; } const pageAnn = findChild(docRoot.children, 'vh2-doc-page-annotations'); if (pageAnn && runtimeSource?.directory) { const runtimePage = findChild(runtimeSource.directory.nodes[0].children, 'vh2-doc-page-annotations'); if (runtimePage?.children) { for (const child of runtimePage.children) { const local = findChild(pageAnn.children, child.id); if (local && child.markdown) { local.markdown = child.markdown; } } } } const overview = findChild(docRoot.children, 'vh2-doc-overview'); const runtimeOverview = findChild(runtimeSource.directory.nodes[0].children, 'vh2-doc-overview'); if (overview && runtimeOverview?.markdown) { overview.markdown = runtimeOverview.markdown; } if (runtimeSource?.nodes) { const markdownMap = { ...(ann.markdownMap || {}) }; for (const node of runtimeSource.nodes) { const local = ann.data.nodes.find((n) => n.id === node.id); if (!local) continue; if (node.annotationText != null && node.annotationText !== '') { local.annotationText = node.annotationText; } if (node.hasMarkdown && node.annotationText) { markdownMap[node.id] = node.annotationText; } if (node.updatedAt) local.updatedAt = node.updatedAt; if (node.controls) local.controls = node.controls; } ann.markdownMap = markdownMap; } ann.data.updatedAt = Date.now(); writeFileSync(annPath, JSON.stringify(ann, null, 2) + '\n', 'utf8'); const pagePath = join(root, 'src/prototypes/vehicle-h2-fee-ledger/H2LedgerPage.jsx'); let page = readFileSync(pagePath, 'utf8'); const prdForJs = prd.replace(/\\/g, '\\\\').replace(/`/g, '\\`').replace(/\$\{/g, '\\${'); const startMarker = 'var H2_LEDGER_REQUIREMENT_DOC = `'; const endMarker = '`;\n\n/** 将 PRD Markdown 排版为 React 节点'; const startIdx = page.indexOf(startMarker); const endIdx = page.indexOf(endMarker); if (startIdx === -1 || endIdx === -1) { throw new Error('H2_LEDGER_REQUIREMENT_DOC markers not found'); } page = page.slice(0, startIdx + startMarker.length) + prdForJs + page.slice(endIdx); writeFileSync(pagePath, page, 'utf8'); console.log('Synced PRD to:', prdPath); console.log('Synced spec:', specPrdPath); console.log('Synced alias:', resourcesAlias); console.log('Synced annotation-source.json and H2LedgerPage.jsx');