#!/usr/bin/env python3 """ NAC Memory System - Export Tool 导出记忆系统为Markdown报告 """ import json from pathlib import Path from datetime import datetime from typing import Dict, Any, List # 记忆系统根目录 MEMORY_ROOT = Path(__file__).parent.parent def load_json(file_path: Path) -> Dict[str, Any]: """加载JSON文件""" with open(file_path, 'r', encoding='utf-8') as f: return json.load(f) def export_documents() -> str: """导出文档知识库""" index_file = MEMORY_ROOT / "documents" / "index.json" if not index_file.exists(): return "## 文档知识库\n\n暂无文档记录。\n" index = load_json(index_file) md = "## 文档知识库\n\n" md += f"总计:{index.get('total_count', 0)} 个文档\n\n" for doc_info in index.get("documents", []): doc_file = MEMORY_ROOT / "documents" / doc_info["file"] if not doc_file.exists(): continue doc = load_json(doc_file) md += f"### {doc.get('title', 'Untitled')}\n\n" md += f"- **ID**: {doc.get('doc_id', 'N/A')}\n" md += f"- **类型**: {doc.get('document_type', 'N/A')}\n" md += f"- **重要性**: {doc.get('importance', 'N/A')}\n" md += f"- **阅读日期**: {doc.get('read_date', 'N/A')}\n" md += f"- **路径**: `{doc.get('path', 'N/A')}`\n\n" md += f"**摘要**:{doc.get('summary', 'N/A')}\n\n" if doc.get('core_concepts'): md += "**核心概念**:\n\n" for concept in doc['core_concepts'][:5]: md += f"- **{concept.get('concept', 'N/A')}**: {concept.get('definition', 'N/A')}\n" md += "\n" if doc.get('key_features'): md += "**关键特性**:\n\n" for feature in doc['key_features'][:5]: md += f"- {feature}\n" md += "\n" md += "---\n\n" return md def export_problems() -> str: """导出问题解决方案库""" index_file = MEMORY_ROOT / "problems" / "index.json" if not index_file.exists(): return "## 问题解决方案库\n\n暂无问题记录。\n" index = load_json(index_file) md = "## 问题解决方案库\n\n" md += f"总计:{index.get('total_count', 0)} 个问题\n\n" for problem_info in index.get("problems", []): problem_file = MEMORY_ROOT / "problems" / problem_info["file"] if not problem_file.exists(): continue problem = load_json(problem_file) md += f"### {problem.get('title', 'Untitled')}\n\n" md += f"- **ID**: {problem.get('problem_id', 'N/A')}\n" md += f"- **日期**: {problem.get('date', 'N/A')}\n" md += f"- **类别**: {problem.get('category', 'N/A')}\n" md += f"- **严重性**: {problem.get('severity', 'N/A')}\n" md += f"- **状态**: {problem.get('status', 'N/A')}\n\n" md += f"**问题描述**:{problem.get('description', 'N/A')}\n\n" if problem.get('root_cause'): md += "**根本原因**:\n\n" cause = problem['root_cause'] if isinstance(cause, dict): md += f"- 主要:{cause.get('primary', 'N/A')}\n" md += f"- 次要:{cause.get('secondary', 'N/A')}\n" else: md += f"- {cause}\n" md += "\n" if problem.get('solution'): md += "**解决方案**:\n\n" solution = problem['solution'] if isinstance(solution, dict): for key, value in solution.items(): md += f"- **{key}**: {value}\n" else: md += f"{solution}\n" md += "\n" if problem.get('lessons_learned'): md += "**经验教训**:\n\n" for lesson in problem['lessons_learned']: md += f"- {lesson}\n" md += "\n" md += "---\n\n" return md def export_decisions() -> str: """导出设计决策日志""" index_file = MEMORY_ROOT / "decisions" / "index.json" if not index_file.exists(): return "## 设计决策日志\n\n暂无决策记录。\n" index = load_json(index_file) md = "## 设计决策日志\n\n" md += f"总计:{index.get('total_count', 0)} 个决策\n\n" for decision_info in index.get("decisions", []): decision_file = MEMORY_ROOT / "decisions" / decision_info["file"] if not decision_file.exists(): continue decision = load_json(decision_file) md += f"### {decision.get('title', 'Untitled')}\n\n" md += f"- **ID**: {decision.get('decision_id', 'N/A')}\n" md += f"- **日期**: {decision.get('date', 'N/A')}\n" md += f"- **类别**: {decision.get('category', 'N/A')}\n" md += f"- **状态**: {decision.get('status', 'N/A')}\n\n" if decision.get('decision'): md += "**决策内容**:\n\n" dec = decision['decision'] if isinstance(dec, dict): md += f"{dec.get('statement', 'N/A')}\n\n" if dec.get('rules'): md += "规则:\n\n" for rule in dec['rules']: md += f"- {rule}\n" md += "\n" else: md += f"{dec}\n\n" if decision.get('rationale'): md += "**决策理由**:\n\n" for reason in decision['rationale']: md += f"- {reason}\n" md += "\n" md += "---\n\n" return md def export_principles() -> str: """导出NAC核心原则""" index_file = MEMORY_ROOT / "principles" / "index.json" if not index_file.exists(): return "## NAC核心原则\n\n暂无原则记录。\n" index = load_json(index_file) md = "## NAC核心原则\n\n" for cat_info in index.get("categories", []): principle_file = MEMORY_ROOT / "principles" / cat_info["file"] if not principle_file.exists(): continue principles = load_json(principle_file) md += f"### {principles.get('title', 'Untitled')}\n\n" md += f"- **类别**: {principles.get('category', 'N/A')}\n" md += f"- **更新日期**: {principles.get('last_updated', 'N/A')}\n\n" # 导出原则 if principles.get('principles'): for principle in principles['principles']: md += f"#### {principle.get('title', 'Untitled')}\n\n" md += f"**ID**: {principle.get('principle_id', 'N/A')}\n\n" md += f"{principle.get('description', 'N/A')}\n\n" if principle.get('must_do'): md += "**必须做**:\n\n" for item in principle['must_do']: md += f"- ✅ {item}\n" md += "\n" if principle.get('must_not_do'): md += "**禁止做**:\n\n" for item in principle['must_not_do']: md += f"- ❌ {item}\n" md += "\n" # 导出术语映射 if principles.get('mappings'): md += "#### 术语映射表\n\n" md += "| 错误术语 | 正确术语 | 中文 | 说明 |\n" md += "|---------|---------|------|------|\n" for mapping in principles['mappings']: wrong = mapping.get('wrong_term', 'N/A') correct = mapping.get('correct_term', 'N/A') chinese = mapping.get('chinese', 'N/A') explanation = mapping.get('explanation', 'N/A') md += f"| {wrong} | {correct} | {chinese} | {explanation} |\n" md += "\n" md += "---\n\n" return md def export_full_report(output_file: Path): """导出完整报告""" today = datetime.now().strftime("%Y-%m-%d") md = f"# NAC项目记忆系统报告\n\n" md += f"导出日期:{today}\n\n" md += "---\n\n" md += export_documents() md += export_problems() md += export_decisions() md += export_principles() md += "---\n\n" md += f"*本报告由NAC记忆系统自动生成*\n" with open(output_file, 'w', encoding='utf-8') as f: f.write(md) print(f"✅ 报告已导出: {output_file}") print(f" 文件大小: {output_file.stat().st_size / 1024:.2f} KB") def main(): """主函数""" import argparse parser = argparse.ArgumentParser(description='NAC Memory System - Export Tool') parser.add_argument('--output', '-o', default='memory_report.md', help='输出文件路径') parser.add_argument('--type', '-t', choices=['document', 'problem', 'decision', 'principle', 'all'], default='all', help='导出类型') args = parser.parse_args() output_file = Path(args.output) if not output_file.is_absolute(): output_file = MEMORY_ROOT.parent / "docs" / output_file if args.type == 'all': export_full_report(output_file) else: md = "" if args.type == 'document': md = export_documents() elif args.type == 'problem': md = export_problems() elif args.type == 'decision': md = export_decisions() elif args.type == 'principle': md = export_principles() with open(output_file, 'w', encoding='utf-8') as f: f.write(md) print(f"✅ 报告已导出: {output_file}") if __name__ == "__main__": main()