cc-os/plugins/memory/hooks/session_end.py

88 lines
2.3 KiB
Python
Raw Normal View History

#!/usr/bin/env python3
"""SessionEnd hook — append a journal entry to the vault's daily log. Fail-open.
The memsearch git sync is split into memsearch_sync.py (its own SessionEnd entry).
"""
import os
import sys
import subprocess
from datetime import datetime, timezone
sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))
import config as config_mod
import hook_io
import session_state
JOURNAL_TEMPLATE = """---
summary: Daily session log
tags: [scope/global, type/log]
---
"""
def main():
inp = hook_io.read_input()
session_id = inp.session_id
reason = inp.reason
if not session_id:
session_id = f"unknown-{os.getpid()}"
cfg = config_mod.load_config()
journal_dir = os.path.join(cfg.vault_path, "journal")
date_str = datetime.now(timezone.utc).strftime("%Y-%m-%d")
journal_path = os.path.join(journal_dir, f"{date_str}.md")
try:
os.makedirs(journal_dir, exist_ok=True)
except Exception:
pass
if not os.path.exists(journal_path):
try:
with open(journal_path, "w") as f:
f.write(JOURNAL_TEMPLATE)
except Exception:
pass
touched = session_state.read_touches(session_id)
touched_list = "\n".join(touched) if touched else "(none)"
try:
r = subprocess.run(
["git", "rev-parse", "--show-toplevel"],
capture_output=True, text=True,
)
if r.returncode == 0 and r.stdout.strip():
project = r.stdout.strip()
else:
project = os.environ.get("CLAUDE_PROJECT_DIR") or "unknown"
except Exception:
project = os.environ.get("CLAUDE_PROJECT_DIR") or "unknown"
timestamp = datetime.now(timezone.utc).strftime("%Y-%m-%dT%H:%M:%SZ")
entry = (
"\n"
f"## Session — {timestamp}\n"
"\n"
f"**Project:** {project}\n"
f"**Reason:** {reason}\n"
"**Vault notes touched:**\n"
f"{touched_list}\n"
)
try:
with open(journal_path, "a") as f:
f.write(entry)
except Exception:
pass
session_state.clear_touches(session_id)
if __name__ == "__main__":
try:
main()
except Exception as e:
print(f"[session-end] error: {e}", file=sys.stderr)
sys.exit(0)