#!/usr/bin/env python3
"""
Извлечение выжимки из файла сессии для анализа Claude.
DEPRECATED: Используйте library.services.session.SessionManager
Использование:
python3 session_extract.py SESSION_ID
python3 session_extract.py 5cdae721
Новый способ:
python3 -m library.services.session extract SESSION_ID
"""
# Делегируем в SessionManager
try:
from library.services.session import SessionManager
USE_NEW_MANAGER = True
except ImportError:
USE_NEW_MANAGER = False
import json
import sys
from pathlib import Path
PROJECTS_DIR = Path.home() / '.claude' / 'projects' / '-opt-claude-workspace'
def extract_session(session_id: str) -> str:
"""Извлечь выжимку из сессии"""
# Найти файл сессии
session_file = None
for f in PROJECTS_DIR.glob(f"{session_id}*.jsonl"):
session_file = f
break
if not session_file or not session_file.exists():
return f"Сессия {session_id} не найдена"
# Читаем сессию
messages = []
with open(session_file, 'r') as f:
for line in f:
try:
msg = json.loads(line.strip())
if msg.get('type') in ('user', 'assistant'):
messages.append(msg)
except json.JSONDecodeError:
pass # Malformed JSON line
# Извлекаем данные
user_messages = []
files_written = set()
files_read = set()
todos = []
for msg in messages:
msg_type = msg.get('type')
if msg_type == 'user':
content = msg.get('message', {}).get('content', '')
if isinstance(content, str) and content.strip():
text = content.strip()
# Пропускаем очень короткие
if len(text) > 3:
user_messages.append(text)
elif msg_type == 'assistant':
content = msg.get('message', {}).get('content', [])
if isinstance(content, list):
for item in content:
if isinstance(item, dict):
tool_name = item.get('name', '')
tool_input = item.get('input', {})
if tool_name == 'Read':
fp = tool_input.get('file_path', '')
if fp:
files_read.add(fp)
elif tool_name in ('Write', 'Edit'):
fp = tool_input.get('file_path', '')
if fp:
files_written.add(fp)
elif tool_name == 'TodoWrite':
todo_list = tool_input.get('todos', [])
for t in todo_list:
todo_text = t.get('content', '')
todo_status = t.get('status', 'pending')
if todo_text:
todos.append({
'content': todo_text,
'status': todo_status
})
# Формируем выжимку
output = []
output.append(f"# СЕССИЯ: {session_file.stem[:16]}...")
output.append(f"Сообщений: {len(messages)}")
output.append("")
# Файлы которые менялись
if files_written:
output.append("## ФАЙЛЫ ИЗМЕНЕНЫ:")
for f in sorted(files_written):
short = f.replace('/opt/claude-workspace/', '')
output.append(f" - {short}")
output.append("")
# TODO - группируем по статусу
completed_todos = []
pending_todos = []
seen = set()
for t in todos:
content = t['content']
if content in seen:
continue
seen.add(content)
if t['status'] == 'completed':
completed_todos.append(content)
else:
pending_todos.append(content)
if completed_todos or pending_todos:
output.append("## TODO ИЗ СЕССИИ:")
if completed_todos:
output.append(" Выполнено:")
for t in completed_todos[:10]:
output.append(f" [x] {t}")
if pending_todos:
output.append(" Не завершено:")
for t in pending_todos[:10]:
output.append(f" [ ] {t}")
output.append("")
# Сообщения пользователя (последние 50)
output.append("## ЗАПРОСЫ ПОЛЬЗОВАТЕЛЯ:")
for i, msg in enumerate(user_messages[-50:], 1):
# Обрезаем длинные
text = msg[:200].replace('\n', ' ')
if len(msg) > 200:
text += "..."
output.append(f" [{i}] {text}")
output.append("")
# Раздел для продолжения
output.append("---")
output.append("## НЕЗАВЕРШЁННЫЕ ЗАДАЧИ:")
output.append("")
if pending_todos:
# Группируем похожие задачи
groups = {}
for t in pending_todos:
# Простая группировка по первому слову
key = t.split()[0] if t.split() else "Другое"
if key not in groups:
groups[key] = []
groups[key].append(t)
idx = 1
for group_name, tasks in groups.items():
if len(tasks) > 3:
# Группа задач
output.append(f" [{idx}] {group_name}... ({len(tasks)} задач)")
for t in tasks[:3]:
output.append(f" - {t[:60]}...")
idx += 1
else:
# Отдельные задачи
for t in tasks:
output.append(f" [{idx}] {t}")
idx += 1
output.append("")
output.append("---")
output.append("ИНСТРУКЦИЯ:")
output.append(" Укажи номера задач для продолжения (например: 1 3 5)")
output.append(" Или: 'все' — взять все задачи")
output.append(" Или: 'дальше' — взять первую задачу и начать")
output.append(" Или: 'пропустить' — закрыть сессию без продолжения")
else:
output.append("Незавершённых TODO не обнаружено.")
output.append("")
output.append("Claude: проанализируй запросы пользователя и определи")
output.append("были ли неявно брошенные задачи.")
output.append("")
return '\n'.join(output)
def main():
if len(sys.argv) < 2:
print("Использование: session_extract.py SESSION_ID")
print("\nДоступные сессии:")
for f in sorted(PROJECTS_DIR.glob("*.jsonl"), key=lambda x: x.stat().st_mtime, reverse=True)[:10]:
print(f" {f.stem[:16]}...")
return
session_id = sys.argv[1]
# Используем новый SessionManager если доступен
if USE_NEW_MANAGER:
manager = SessionManager()
print(manager.extract_summary(session_id))
else:
print(extract_session(session_id))
if __name__ == '__main__':
main()