#!/usr/bin/env node const fs = require('fs'); const path = require('path'); const { readMemory, applyFeedbackRecordsToMemory } = require('../mcp/src/features/tihao-sourcing/preference-memory'); function main() { const args = parseArgs(process.argv.slice(2)); if (!args.feedback && !args.feedbackPath) { throw new Error('Usage: node scripts/import-feedback-memory.js --feedback --memory '); } const feedbackPath = path.resolve(args.feedback || args.feedbackPath); const memoryPath = path.resolve(args.memory || args.memoryPath || 'memory/tihao-preference-memory.json'); const records = readFeedbackCsv(feedbackPath); const memory = applyFeedbackRecordsToMemory(readMemory(memoryPath), records); fs.mkdirSync(path.dirname(memoryPath), { recursive: true }); fs.writeFileSync(memoryPath, JSON.stringify(memory, null, 2), 'utf8'); const summary = [ '反馈已导入提号偏好记忆。', `反馈文件:${feedbackPath}`, `记忆文件:${memoryPath}`, `导入记录:${records.length}`, `累计反馈:${memory.feedbackRecords.length}`, `拉黑/降权账号:${memory.blockedCreators.length}`, `个人偏好:${memory.personalPreferences.length}`, `客户/品牌偏好:${memory.clientBrandPreferences.length}`, `团队规则候选:${memory.teamRuleCandidates.length}`, `团队规则升级建议:${(memory.teamRuleSuggestions || []).length}` ].join('\n'); if (args.assistantMessageOnly) console.log(summary); else console.log(`TIHAO_FEEDBACK_IMPORT=${JSON.stringify({ status: 'ok', summary, data: { memory }, files: [memoryPath] })}`); } function readFeedbackCsv(file) { const text = fs.readFileSync(file, 'utf8').replace(/^\uFEFF/, ''); const lines = text.split(/\r?\n/).filter(Boolean); const header = parseCsvLine(lines.shift() || ''); return lines.map(line => { const cells = parseCsvLine(line); const row = {}; header.forEach((key, index) => { row[key] = cells[index] || ''; }); return row; }); } function parseCsvLine(line) { const cells = []; let current = ''; let quoted = false; for (let i = 0; i < line.length; i += 1) { const char = line[i]; if (char === '"' && quoted && line[i + 1] === '"') { current += '"'; i += 1; } else if (char === '"') { quoted = !quoted; } else if (char === ',' && !quoted) { cells.push(current); current = ''; } else { current += char; } } cells.push(current); return cells; } function parseArgs(argv) { const args = {}; for (let i = 0; i < argv.length; i += 1) { const raw = argv[i]; if (!raw.startsWith('--')) continue; const key = raw.slice(2).replace(/-([a-z])/g, (_, char) => char.toUpperCase()); const next = argv[i + 1]; if (!next || next.startsWith('--')) args[key] = true; else { args[key] = next; i += 1; } } return args; } if (require.main === module) { try { main(); } catch (error) { console.error(error && error.stack ? error.stack : String(error)); process.exit(1); } } module.exports = { readFeedbackCsv };