"""将外部生成的摘要导入到双索引文件。 精简索引 (_session_index.json):仅主对话 完整索引 (_session_index_full.json):主对话 + 子代理 输入文件格式 (_summaries.json): { "exec_id_short": "摘要文本", "447a8e20": "完成了 Kiro 日志存储结构的逆向工程...", ... } 用法: python -B scripts/ops/import_session_summaries.py export/session_summaries/_summaries.json python -B scripts/ops/import_session_summaries.py --dry-run export/session_summaries/_summaries.json """ import json import sys from pathlib import Path from _env_paths import ensure_repo_root ensure_repo_root() INDEX_DIR = Path("docs/audit/session_logs") INDEX_PATH = INDEX_DIR / "_session_index.json" INDEX_FULL_PATH = INDEX_DIR / "_session_index_full.json" def load_json(path: Path) -> dict: if not path.exists(): return {"version": 2, "entries": {}} return json.loads(path.read_text(encoding="utf-8")) def save_json(path: Path, data: dict): path.write_text( json.dumps(data, indent=2, ensure_ascii=False) + "\n", encoding="utf-8", ) def import_to_index(entries: dict, summaries: dict, dry_run: bool) -> tuple[int, int]: """将摘要写入索引 entries,返回 (matched, not_found)""" matched = 0 not_found = 0 for short_id, desc in summaries.items(): found = False for full_id in entries: if full_id.startswith(short_id): if not dry_run: entries[full_id]["description"] = desc matched += 1 found = True break if not found: not_found += 1 return matched, not_found def main(): import argparse parser = argparse.ArgumentParser(description="导入摘要到 session 双索引") parser.add_argument("summaries_file", help="_summaries.json 文件路径") parser.add_argument("--dry-run", action="store_true", help="只预览不写入") args = parser.parse_args() summaries = json.loads(Path(args.summaries_file).read_text(encoding="utf-8")) print(f"读取 {len(summaries)} 条摘要") # 精简索引 index = load_json(INDEX_PATH) entries = index.get("entries", {}) m1, nf1 = import_to_index(entries, summaries, args.dry_run) print(f"精简索引: {m1} 条匹配, {nf1} 条未找到") # 完整索引 full_index = load_json(INDEX_FULL_PATH) full_entries = full_index.get("entries", {}) m2, nf2 = import_to_index(full_entries, summaries, args.dry_run) print(f"完整索引: {m2} 条匹配, {nf2} 条未找到") if not args.dry_run: save_json(INDEX_PATH, index) save_json(INDEX_FULL_PATH, full_index) print("写入完成") else: print("(dry-run 模式,未写入)") if __name__ == "__main__": main()