Initial commit
This commit is contained in:
400
commands/save-session.md
Normal file
400
commands/save-session.md
Normal file
@@ -0,0 +1,400 @@
|
||||
---
|
||||
allowed-tools: Read, Write, Bash, Grep, Glob
|
||||
description: 总结并保存当前会话到本地存储
|
||||
---
|
||||
|
||||
智能分析当前会话内容,提取关键信息(项目进度、实施方案、关键决策、文件变更),并保存到分层存储结构中。
|
||||
|
||||
**核心特性**:
|
||||
- 📊 **智能提取**: 自动识别 TodoWrite、AskUserQuestion、文件操作等关键信息
|
||||
- 💾 **分层存储**: 摘要文件 + 完整日志,兼顾查询效率和数据完整性
|
||||
- 🔍 **防失真**: 保留完整对话记录,避免压缩导致信息丢失
|
||||
- 🌐 **跨平台**: 完全兼容 Windows / macOS / Linux
|
||||
|
||||
---
|
||||
|
||||
## 执行步骤
|
||||
|
||||
### 1. 定位当前会话文件
|
||||
|
||||
找到 Claude Code 当前会话的 JSONL 文件。
|
||||
|
||||
**位置**:`~/.claude/projects/` 目录下
|
||||
|
||||
**匹配规则**:
|
||||
- 项目目录名包含当前工作目录的路径信息
|
||||
- 例如:项目在 `/Users/user/my-project`
|
||||
- 对应目录可能是:`-Users-user-my-project/`
|
||||
- 文件名格式:`{session-uuid}.jsonl`
|
||||
- 排除 `agent-` 开头的文件
|
||||
- 选择最新的文件(按修改时间)
|
||||
|
||||
**如果找不到**:
|
||||
- 输出错误信息
|
||||
- 说明可能原因:
|
||||
- 当前不在 Claude Code 会话中
|
||||
- 会话数据已被清理
|
||||
- 项目路径不匹配
|
||||
|
||||
**提取信息**:
|
||||
- 会话文件的完整路径
|
||||
- 会话 UUID(文件名不含扩展名)
|
||||
|
||||
### 2. 读取并解析会话数据
|
||||
|
||||
a. 使用 Read 工具读取整个 JSONL 文件
|
||||
```bash
|
||||
# 读取会话文件
|
||||
Read tool: $CURRENT_SESSION
|
||||
```
|
||||
|
||||
b. 解析 JSONL 数据并提取关键信息
|
||||
- 使用 Python 脚本处理 JSON 数据(跨平台兼容)
|
||||
- 提取以下信息:
|
||||
* 第一条用户消息(作为会话标题)
|
||||
* 所有用户消息和 AI 响应
|
||||
* TodoWrite 工具调用(进度信息)
|
||||
* AskUserQuestion 工具调用(关键决策)
|
||||
* Write/Edit 工具调用(文件变更)
|
||||
* 消息时间戳(开始和结束时间)
|
||||
|
||||
c. 解析脚本实现
|
||||
```python
|
||||
import json
|
||||
import sys
|
||||
from datetime import datetime
|
||||
|
||||
# 读取 JSONL 并解析
|
||||
messages = []
|
||||
todos = []
|
||||
decisions = []
|
||||
file_changes = []
|
||||
|
||||
for line in sys.stdin:
|
||||
msg = json.loads(line.strip())
|
||||
messages.append(msg)
|
||||
|
||||
# 提取 TodoWrite
|
||||
if msg.get('type') == 'tool_use' and msg.get('name') == 'TodoWrite':
|
||||
todos.append(msg.get('input', {}).get('todos', []))
|
||||
|
||||
# 提取 AskUserQuestion
|
||||
if msg.get('type') == 'tool_use' and msg.get('name') == 'AskUserQuestion':
|
||||
decisions.append({
|
||||
'timestamp': msg.get('timestamp'),
|
||||
'questions': msg.get('input', {}).get('questions', []),
|
||||
'answers': msg.get('input', {}).get('answers', {})
|
||||
})
|
||||
|
||||
# 提取文件操作
|
||||
if msg.get('type') == 'tool_use' and msg.get('name') in ['Write', 'Edit']:
|
||||
file_changes.append({
|
||||
'operation': 'created' if msg.get('name') == 'Write' else 'modified',
|
||||
'path': msg.get('input', {}).get('file_path', ''),
|
||||
'timestamp': msg.get('timestamp')
|
||||
})
|
||||
|
||||
# 输出结果
|
||||
print(json.dumps({
|
||||
'messages': messages,
|
||||
'todos': todos,
|
||||
'decisions': decisions,
|
||||
'file_changes': file_changes
|
||||
}))
|
||||
```
|
||||
|
||||
### 3. 生成会话摘要
|
||||
|
||||
a. 提取会话元数据
|
||||
```json
|
||||
{
|
||||
"version": "1.0",
|
||||
"sessionId": "{SESSION_UUID}",
|
||||
"projectPath": "{CURRENT_DIR}",
|
||||
"projectName": "{从路径提取最后一部分}",
|
||||
"savedAt": "{当前时间 ISO 8601}",
|
||||
"startTime": "{第一条消息时间}",
|
||||
"endTime": "{最后一条消息时间}",
|
||||
"messageCount": {总消息数},
|
||||
"userMessageCount": {用户消息数},
|
||||
"assistantMessageCount": {AI 响应数}
|
||||
}
|
||||
```
|
||||
|
||||
b. 生成会话概览
|
||||
- 标题:使用第一条用户消息(限制 100 字符)
|
||||
- 描述:简要总结会话内容(AI 生成,100-200 字)
|
||||
- 关键词:从标题和主要操作中提取(3-5 个)
|
||||
|
||||
c. 整理进度信息
|
||||
- 从最后一次 TodoWrite 调用中提取任务列表
|
||||
- 统计已完成/进行中/待办任务数量
|
||||
- 保留任务的 content、status、activeForm
|
||||
|
||||
d. 整理关键决策
|
||||
- 记录所有 AskUserQuestion 交互
|
||||
- 包含问题、选项、用户答案
|
||||
- 记录时间戳
|
||||
|
||||
e. 整理文件变更
|
||||
- 列出所有文件操作
|
||||
- 记录操作类型(创建/修改/删除)
|
||||
- 记录相对路径和时间戳
|
||||
|
||||
f. 检测实施方案文档
|
||||
- 搜索 docs/todo/ 目录下的方案文档
|
||||
- 如果找到,提取文件路径
|
||||
- 提取方案要点(前 3-5 个要点)
|
||||
|
||||
### 4. 保存到分层存储
|
||||
|
||||
a. 创建存储目录(项目本地)
|
||||
```bash
|
||||
# 存储目录结构(相对路径,跨平台兼容)
|
||||
SUMMARY_DIR="./.claude-sessions/summaries/$SESSION_UUID"
|
||||
mkdir -p "$SUMMARY_DIR"
|
||||
|
||||
# 创建导出目录
|
||||
EXPORT_DIR="./.claude-sessions/exports"
|
||||
mkdir -p "$EXPORT_DIR"
|
||||
```
|
||||
|
||||
b. 写入 summary.json
|
||||
- 使用 Write 工具写入摘要文件
|
||||
- 包含所有元数据、概览、进度、决策、文件变更信息
|
||||
- 格式化 JSON(便于阅读)
|
||||
|
||||
c. 复制完整 JSONL(使用 Bash cp 命令或 Read+Write 工具)
|
||||
- 将找到的会话文件复制到存储目录
|
||||
- 目标:`$SUMMARY_DIR/details.jsonl`
|
||||
- 确保完整复制,不修改内容
|
||||
|
||||
d. 验证保存成功
|
||||
- 检查文件是否存在
|
||||
- 验证文件大小 > 0
|
||||
- 如果失败,输出错误信息
|
||||
|
||||
### 5. 输出确认信息
|
||||
|
||||
输出格式化的成功信息:
|
||||
|
||||
```
|
||||
✅ 会话已成功保存!
|
||||
|
||||
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
||||
📄 保存位置(项目本地)
|
||||
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
||||
存储目录: ./.claude-sessions/summaries/{session-uuid}/
|
||||
├── summary.json ({文件大小})
|
||||
└── details.jsonl ({文件大小})
|
||||
|
||||
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
||||
📊 会话信息
|
||||
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
||||
会话标题: {标题}
|
||||
项目名称: {项目名}
|
||||
会话时间: {开始时间} - {结束时间}
|
||||
消息总数: {数量} ({用户消息数} 用户 + {AI消息数} 助手)
|
||||
|
||||
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
||||
📈 工作进度
|
||||
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
||||
✅ 已完成: {数量}
|
||||
🔄 进行中: {数量}
|
||||
📋 待办: {数量}
|
||||
总计: {总数}
|
||||
|
||||
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
||||
📂 文件变更
|
||||
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
||||
{列出前5个文件变更,格式:}
|
||||
✨ 已创建: path/to/file1
|
||||
📝 已修改: path/to/file2
|
||||
...
|
||||
|
||||
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
||||
💡 下一步
|
||||
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
||||
使用以下命令在新会话中继续工作:
|
||||
/session-manager:continue
|
||||
|
||||
🤖 Generated by session-manager plugin
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 错误处理
|
||||
|
||||
### 场景 1: 会话文件不存在
|
||||
|
||||
```
|
||||
❌ 错误:找不到当前会话文件
|
||||
|
||||
可能原因:
|
||||
1. 当前不在有效的 Claude Code 会话中
|
||||
2. 会话数据已被清理
|
||||
3. 项目路径编码错误
|
||||
|
||||
建议:
|
||||
- 确保在 Claude Code 会话中执行此命令
|
||||
- 检查 ~/.claude/projects/ 目录是否存在
|
||||
- 尝试在新会话中重试
|
||||
```
|
||||
|
||||
### 场景 2: 存储目录创建失败
|
||||
|
||||
```
|
||||
❌ 错误:无法创建存储目录
|
||||
|
||||
目标目录: {目录路径}
|
||||
|
||||
可能原因:
|
||||
1. 磁盘空间不足
|
||||
2. 权限不足
|
||||
3. 目录路径无效
|
||||
|
||||
建议:
|
||||
- 检查磁盘空间:df -h
|
||||
- 检查目录权限:ls -ld ~/.claude
|
||||
- 手动创建目录:mkdir -p {目录路径}
|
||||
```
|
||||
|
||||
### 场景 3: JSONL 解析失败
|
||||
|
||||
```
|
||||
❌ 错误:会话数据解析失败
|
||||
|
||||
文件: {文件路径}
|
||||
错误: {错误信息}
|
||||
|
||||
可能原因:
|
||||
1. JSONL 文件格式损坏
|
||||
2. 文件编码问题
|
||||
3. 不完整的 JSON 行
|
||||
|
||||
建议:
|
||||
- 检查文件完整性
|
||||
- 尝试使用文本编辑器查看文件
|
||||
- 联系支持获取帮助
|
||||
```
|
||||
|
||||
### 场景 4: 文件写入失败
|
||||
|
||||
```
|
||||
❌ 错误:无法写入摘要文件
|
||||
|
||||
目标文件: {文件路径}
|
||||
错误: {错误信息}
|
||||
|
||||
可能原因:
|
||||
1. 磁盘空间不足
|
||||
2. 文件权限问题
|
||||
3. 目标目录不存在
|
||||
|
||||
建议:
|
||||
- 检查磁盘空间:df -h
|
||||
- 检查文件权限
|
||||
- 确保存储目录存在
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 跨平台兼容性
|
||||
|
||||
### 路径处理
|
||||
- ✅ 使用 `$HOME` 而非 `~`
|
||||
- ✅ 使用 `pwd` 获取绝对路径
|
||||
- ✅ 使用 `sed` 进行路径编码(标准工具)
|
||||
|
||||
### JSON 处理
|
||||
- ✅ 优先使用 Python 3(系统自带)
|
||||
- ✅ 备选:使用 jq(如果可用)
|
||||
- ✅ 使用标准 JSON 格式
|
||||
|
||||
### 时间处理
|
||||
- ✅ 使用 `date -u` 生成 UTC 时间
|
||||
- ✅ 使用 ISO 8601 格式(跨平台标准)
|
||||
|
||||
### 文件操作
|
||||
- ✅ 使用 `cp` 复制文件
|
||||
- ✅ 使用 `mkdir -p` 创建目录
|
||||
- ✅ 使用 `ls -t` 排序文件
|
||||
|
||||
---
|
||||
|
||||
## 性能考虑
|
||||
|
||||
### 大文件处理
|
||||
- 会话文件 < 1MB:直接处理
|
||||
- 会话文件 1MB - 10MB:正常处理,提示可能需要等待
|
||||
- 会话文件 > 10MB:警告用户,建议分批保存
|
||||
|
||||
### 内存使用
|
||||
- 一次性读取整个 JSONL 文件到内存
|
||||
- 对于大文件,可考虑流式处理(未来优化)
|
||||
|
||||
### 存储空间
|
||||
- 每个会话约占用 100KB - 2MB
|
||||
- 建议定期清理旧会话(手动或自动)
|
||||
|
||||
---
|
||||
|
||||
## 使用示例
|
||||
|
||||
### 基本使用
|
||||
```bash
|
||||
# 在工作一段时间后保存会话
|
||||
/session-manager:save
|
||||
|
||||
# 输出:
|
||||
# ✅ 会话已成功保存!
|
||||
# 会话标题: 实现用户认证功能
|
||||
# 进度: 5/8 已完成
|
||||
# ...
|
||||
```
|
||||
|
||||
### 长期项目
|
||||
```bash
|
||||
# 每天结束工作前保存
|
||||
/session-manager:save
|
||||
|
||||
# 第二天开始工作时恢复
|
||||
/session-manager:continue
|
||||
```
|
||||
|
||||
### 任务切换
|
||||
```bash
|
||||
# 项目 A - 保存当前进度
|
||||
/session-manager:save
|
||||
|
||||
# 切换到项目 B
|
||||
cd ~/project-b
|
||||
|
||||
# 项目 B - 保存进度
|
||||
/session-manager:save
|
||||
|
||||
# 稍后回到项目 A
|
||||
cd ~/project-a
|
||||
/session-manager:continue
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
**最佳实践**:
|
||||
1. 🕐 定期保存:建议每完成一个重要阶段就保存一次
|
||||
2. 📝 清晰命名:第一条消息尽量描述清楚要做什么
|
||||
3. 📋 使用 TodoWrite:便于跟踪和恢复进度
|
||||
4. 💬 记录决策:重要选择使用 AskUserQuestion 记录
|
||||
5. 🗂️ 整理文件:重要方案保存到 docs/todo/ 目录
|
||||
|
||||
---
|
||||
|
||||
**注意事项**:
|
||||
- ⚠️ 此命令不会修改原始会话数据
|
||||
- ⚠️ 保存的数据仅在本地存储
|
||||
- ⚠️ 建议定期备份 ~/.claude/session-summary/ 目录
|
||||
- ⚠️ 敏感信息(API 密钥、密码)也会被保存,注意安全
|
||||
|
||||
---
|
||||
|
||||
🤖 Generated with Claude Code
|
||||
Reference in New Issue
Block a user