#!/usr/bin/env python3 """session_log — agentStop 时记录本次对话的完整日志。 收集来源: - 环境变量 AGENT_OUTPUT(Kiro 注入的 agent 输出) - 环境变量 USER_PROMPT(最近一次用户输入) - .kiro/.last_prompt_id.json(Prompt ID 溯源) - .kiro/.audit_state.json(变更文件列表) - git diff --stat(变更统计) 输出:docs/audit/session_logs/session_.md """ import json import os import subprocess import sys from datetime import datetime, timezone, timedelta TZ_TAIPEI = timezone(timedelta(hours=8)) LOG_DIR = os.path.join("docs", "audit", "session_logs") STATE_PATH = os.path.join(".kiro", ".audit_state.json") PROMPT_ID_PATH = os.path.join(".kiro", ".last_prompt_id.json") def now_taipei(): return datetime.now(TZ_TAIPEI) def safe_read_json(path): if not os.path.isfile(path): return {} try: with open(path, "r", encoding="utf-8") as f: return json.load(f) except Exception: return {} def git_diff_stat(): try: r = subprocess.run( ["git", "diff", "--stat", "HEAD"], capture_output=True, text=True, timeout=10 ) return r.stdout.strip() if r.returncode == 0 else "(git diff failed)" except Exception: return "(git not available)" def git_status_short(): try: r = subprocess.run( ["git", "status", "--short"], capture_output=True, text=True, timeout=10 ) return r.stdout.strip() if r.returncode == 0 else "" except Exception: return "" def main(): now = now_taipei() ts = now.strftime("%Y%m%d_%H%M%S") timestamp_display = now.strftime("%Y-%m-%d %H:%M:%S %z") # 收集数据 agent_output = os.environ.get("AGENT_OUTPUT", "") user_prompt = os.environ.get("USER_PROMPT", "") prompt_info = safe_read_json(PROMPT_ID_PATH) audit_state = safe_read_json(STATE_PATH) prompt_id = prompt_info.get("prompt_id", "unknown") # 截断超长内容,避免日志文件过大 max_len = 50000 if len(agent_output) > max_len: agent_output = agent_output[:max_len] + "\n\n[TRUNCATED: output exceeds 50KB]" if len(user_prompt) > 10000: user_prompt = user_prompt[:10000] + "\n\n[TRUNCATED: prompt exceeds 10KB]" diff_stat = git_diff_stat() status_short = git_status_short() changed_files = audit_state.get("changed_files", []) os.makedirs(LOG_DIR, exist_ok=True) filename = f"session_{ts}.md" filepath = os.path.join(LOG_DIR, filename) content = f"""# Session Log — {timestamp_display} - Prompt-ID: `{prompt_id}` - Audit Required: `{audit_state.get('audit_required', 'N/A')}` - Reasons: {', '.join(audit_state.get('reasons', [])) or 'none'} ## User Input ```text {user_prompt or '(not captured)'} ``` ## Agent Output ```text {agent_output or '(not captured)'} ``` ## Changed Files ({len(changed_files)}) ``` {chr(10).join(changed_files[:80]) if changed_files else '(none)'} ``` ## Git Diff Stat ``` {diff_stat} ``` ## Git Status ``` {status_short or '(clean)'} ``` """ with open(filepath, "w", encoding="utf-8") as f: f.write(content) if __name__ == "__main__": try: main() except Exception: pass