From 6a4a4644313108be52407872907745ad3dd9e749 Mon Sep 17 00:00:00 2001 From: Zhongwei Li Date: Sat, 29 Nov 2025 18:08:43 +0800 Subject: [PATCH] Initial commit --- .claude-plugin/plugin.json | 12 + README.md | 3 + commands/continue-session.md | 857 +++++++++++++++++++++++++++++++++++ commands/save-session.md | 400 ++++++++++++++++ plugin.lock.json | 49 ++ 5 files changed, 1321 insertions(+) create mode 100644 .claude-plugin/plugin.json create mode 100644 README.md create mode 100644 commands/continue-session.md create mode 100644 commands/save-session.md create mode 100644 plugin.lock.json diff --git a/.claude-plugin/plugin.json b/.claude-plugin/plugin.json new file mode 100644 index 0000000..5e1f68e --- /dev/null +++ b/.claude-plugin/plugin.json @@ -0,0 +1,12 @@ +{ + "name": "session-manager", + "description": "会话管理插件 - 智能保存和恢复 Claude Code 会话,支持进度跟踪和工作连续性", + "version": "1.0.0", + "author": { + "name": "Wang Xuecheng", + "email": "ahut17353766123@gmail.com" + }, + "commands": [ + "./commands" + ] +} \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 0000000..c82b762 --- /dev/null +++ b/README.md @@ -0,0 +1,3 @@ +# session-manager + +会话管理插件 - 智能保存和恢复 Claude Code 会话,支持进度跟踪和工作连续性 diff --git a/commands/continue-session.md b/commands/continue-session.md new file mode 100644 index 0000000..648c749 --- /dev/null +++ b/commands/continue-session.md @@ -0,0 +1,857 @@ +--- +allowed-tools: Read, Write, AskUserQuestion, Bash, Grep, Glob +description: 搜索并继续之前保存的会话 +--- + +智能搜索已保存的会话,支持按项目、时间、关键词过滤,选择后生成 Markdown 格式的会话摘要供在新会话中继续工作。 + +**核心特性**: +- 🔍 **智能搜索**: 支持按项目、时间范围、关键词搜索 +- 📋 **可视化列表**: 清晰展示会话信息(标题、时间、进度) +- 📝 **完整导出**: 生成包含进度、方案、决策的 Markdown 文档 +- 💡 **行动建议**: 自动生成后续工作建议 + +--- + +## 执行步骤 + +### 1. 扫描已保存的会话 + +a. 检查存储目录是否存在(项目本地) + ```bash + SUMMARY_BASE="./.claude-sessions/summaries" + + if [ ! -d "$SUMMARY_BASE" ]; then + echo "❌ 错误:未找到已保存的会话" + echo "提示:使用 /session-manager:save 保存当前会话" + echo "📁 会话将保存在项目目录: ./.claude-sessions/" + exit 1 + fi + ``` + +b. 查找所有摘要文件(项目本地) + ```bash + # 查找当前项目的所有会话摘要 + find "$SUMMARY_BASE" -maxdepth 2 -name "summary.json" -type f + ``` + +c. 读取并解析所有摘要文件 + - 使用 Read 工具读取每个 summary.json + - 提取关键信息用于展示: + * 会话标题 + * 项目名称 + * 保存时间 + * 进度信息(已完成/总数) + * 会话 ID 和存储路径 + +d. 按保存时间排序(最新的在前) + ```bash + # 使用 Python 脚本读取和排序 + python3 << 'EOF' + import json + import glob + import os + from datetime import datetime + + summary_files = glob.glob(os.path.expanduser("~/.claude/session-summary/**/summary.json"), recursive=True) + + sessions = [] + for file_path in summary_files: + with open(file_path, 'r', encoding='utf-8') as f: + data = json.load(f) + data['_file_path'] = file_path + sessions.append(data) + + # 按 savedAt 时间排序 + sessions.sort(key=lambda x: x.get('savedAt', ''), reverse=True) + + # 输出 JSON + print(json.dumps(sessions, ensure_ascii=False)) + EOF + ``` + +### 2. 首次展示(最近 10 个) + +a. 提取最近 10 个会话信息 + +b. 格式化展示选项 + ``` + 每个选项格式: + label: "[时间] 项目名 - 会话标题" + description: "进度:X/Y 已完成 | 文件变更:Z 个" + ``` + +c. 使用 AskUserQuestion 展示列表 + ```yaml + question: "选择要继续的会话(显示最近 10 个):" + header: "会话列表" + multiSelect: false + options: + - label: "🔍 搜索和过滤" + description: "按项目、时间或关键词搜索会话" + + - label: "[2025-11-03 16:00] claude-code-init - 添加会话管理插件" + description: "进度:4/6 已完成 | 文件变更:3 个" + + - label: "[2025-11-03 14:30] my-project - 实现用户认证" + description: "进度:5/8 已完成 | 文件变更:12 个" + + ... (最多 10 个) + + - label: "📚 查看更多..." + description: "显示更多会话(第 11-20 个)" + ``` + +### 3. 搜索和过滤功能 + +#### 如果用户选择"搜索和过滤" + +a. 提供搜索选项 + ```yaml + 使用 AskUserQuestion: + question: "选择搜索条件:" + header: "搜索选项" + multiSelect: false + options: + - label: "按项目过滤" + description: "只显示特定项目的会话" + + - label: "按时间范围" + description: "选择时间范围(今天、本周、本月、自定义)" + + - label: "按关键词搜索" + description: "在标题和描述中搜索关键词" + + - label: "返回会话列表" + description: "返回主列表" + ``` + +#### 场景 A: 按项目过滤 + +1. 提取所有唯一的项目名称 + ```python + projects = list(set(s['projectName'] for s in sessions)) + projects.sort() + ``` + +2. 展示项目列表供选择 + ```yaml + question: "选择项目:" + header: "项目过滤" + multiSelect: false + options: + - label: "项目名称 1" + description: "{该项目的会话数} 个会话" + - label: "项目名称 2" + description: "{该项目的会话数} 个会话" + ... + ``` + +3. 过滤并展示该项目的会话列表 + +#### 场景 B: 按时间范围 + +1. 提供时间范围选项 + ```yaml + question: "选择时间范围:" + header: "时间过滤" + multiSelect: false + options: + - label: "今天" + description: "只显示今天保存的会话" + + - label: "本周" + description: "显示本周保存的会话" + + - label: "本月" + description: "显示本月保存的会话" + + - label: "最近 7 天" + description: "显示最近 7 天的会话" + + - label: "最近 30 天" + description: "显示最近 30 天的会话" + ``` + +2. 根据选择过滤会话 + ```python + from datetime import datetime, timedelta + + now = datetime.now() + + # 根据选择计算时间范围 + if choice == "今天": + start = now.replace(hour=0, minute=0, second=0) + elif choice == "本周": + start = now - timedelta(days=now.weekday()) + elif choice == "本月": + start = now.replace(day=1, hour=0, minute=0, second=0) + # ... + + # 过滤会话 + filtered = [s for s in sessions if datetime.fromisoformat(s['savedAt']) >= start] + ``` + +3. 展示过滤后的会话列表 + +#### 场景 C: 按关键词搜索 + +1. 询问用户输入关键词 + ```yaml + question: "请输入搜索关键词:" + header: "关键词搜索" + multiSelect: false + options: + - label: "输入关键词" + description: "在标题、描述、关键词中搜索" + ``` + +2. 从用户输入中提取关键词(使用 Other 选项) + +3. 在会话数据中搜索 + ```python + keyword = user_input.lower() + + filtered = [] + for session in sessions: + # 搜索标题 + if keyword in session['overview']['title'].lower(): + filtered.append(session) + continue + + # 搜索描述 + if keyword in session['overview'].get('description', '').lower(): + filtered.append(session) + continue + + # 搜索关键词列表 + if any(keyword in kw.lower() for kw in session['overview'].get('keywords', [])): + filtered.append(session) + continue + ``` + +4. 展示搜索结果 + - 如果找到 0 个:提示未找到,返回主列表 + - 如果找到 1-10 个:直接展示 + - 如果找到 >10 个:展示前 10 个 + "查看更多" + +### 4. 用户选择会话 + +#### 提取会话数据 + +1. 根据用户选择,定位到对应的 summary.json + +2. 读取完整的摘要数据 + ```bash + # 读取 summary.json + Read tool: {SESSION_DIR}/summary.json + ``` + +3. 可选:读取详细日志(如果需要提取更多上下文) + ```bash + # 读取 details.jsonl(可选) + Read tool: {SESSION_DIR}/details.jsonl + ``` + +### 5. 生成导出文件 + +#### 创建导出目录(项目本地) +```bash +EXPORT_DIR="./.claude-sessions/exports" +mkdir -p "$EXPORT_DIR" + +# 生成文件名 +TIMESTAMP=$(date +"%Y-%m-%d-%H-%M") +EXPORT_FILE="$EXPORT_DIR/${TIMESTAMP}-${SESSION_UUID}.md" +``` + +#### 生成 Markdown 内容 + +使用以下模板生成导出文件: + +```markdown +# 会话恢复:{会话标题} + +> **会话 ID**: {uuid} +> **项目**: {项目名称} (`{项目路径}`) +> **会话时间**: {开始时间} - {结束时间} +> **保存时间**: {保存时间} +> **消息总数**: {消息数} ({用户消息数} 用户 + {AI消息数} 助手) + +--- + +## 📋 工作概述 + +{从 summary.json 提取的描述} + +**关键词**: {关键词1}, {关键词2}, {关键词3} + +--- + +## 📈 项目进度 + +### ✅ 已完成任务 ({已完成数量}) + +{遍历 todos,筛选 status === "completed"} +- [x] {任务1内容} +- [x] {任务2内容} +... + +### 🔄 进行中任务 ({进行中数量}) + +{遍历 todos,筛选 status === "in_progress"} +- [ ] {任务内容} - 🔄 {activeForm} + +### 📋 待办任务 ({待办数量}) + +{遍历 todos,筛选 status === "pending"} +- [ ] {任务内容} + +**进度总览**: {已完成}/{总数} 已完成 ({完成百分比}%) + +--- + +## 📐 实施方案 + +{如果 implementation.hasDesignDoc === true} + +**方案文档**: `{implementation.designDocPath}` + +### 主要变更点 + +{遍历 implementation.mainChanges} +1. {变更点1} +2. {变更点2} +... + +{如果没有方案文档} +_本会话未包含正式的实施方案文档_ + +--- + +## 💡 关键决策 + +{遍历 keyDecisions} + +### 决策 {序号} - {格式化时间} + +**问题**: {decision.question} + +**选择**: {decision.answer} + +{如果有多个选项,展示所有选项} +_可选项_: +- {选项1描述} +- {选项2描述} +... + +--- +{如果没有关键决策} +_本会话未记录关键决策_ + +--- + +## 📂 文件变更记录 + +{遍历 filesModified,按类型分组} + +### ✨ 已创建文件 ({创建文件数量}) + +{筛选 operation === "created"} +- `{相对路径1}` - {格式化时间} +- `{相对路径2}` - {格式化时间} +... + +### 📝 已修改文件 ({修改文件数量}) + +{筛选 operation === "modified"} +- `{相对路径1}` - {格式化时间} +- `{相对路径2}` - {格式化时间} +... + +### 🗑️ 已删除文件 ({删除文件数量}) + +{筛选 operation === "deleted"} +- `{相对路径1}` - {格式化时间} +... + +{如果没有文件变更} +_本会话未修改任何文件_ + +--- + +## 🎯 后续行动建议 + +根据当前进度和待办任务,建议: + +{自动生成建议,基于:} +1. 继续完成进行中的任务: + {如果有 in_progress 任务} + - {任务内容} - 当前状态:{activeForm} + +2. 开始下一个待办任务: + {取第一个 pending 任务} + - {任务内容} + +3. 验证已完成功能: + {基于已完成的任务生成验证建议} + - 测试 {相关功能} + - 验证 {相关文件} 的正确性 + +4. 更新文档: + {如果有文档相关的待办} + - 完善 {文档名称} + +{如果所有任务都已完成} +🎉 **恭喜!所有任务已完成!** + +建议: +- 进行全面测试 +- 更新项目文档 +- 准备提交代码 + +--- + +## 📚 详细对话记录 + +完整的对话记录已保存在: + +``` +{SESSION_DIR}/details.jsonl +``` + +如需查看完整上下文,可以: +1. 使用文本编辑器打开上述文件 +2. 使用 `cat` 命令查看:`cat {SESSION_DIR}/details.jsonl` +3. 使用 `jq` 格式化查看:`jq -r '.content' {SESSION_DIR}/details.jsonl` + +--- + + + +--- + +## 🔗 如何继续工作 + +### 方式 1:粘贴到新会话(推荐) + +1. 复制上述内容(从"工作概述"到"后续行动建议") +2. 在新 Claude Code 会话中粘贴 +3. 添加你的新请求,例如: + ``` + 继续之前的工作,{描述你要做什么} + ``` + +### 方式 2:引用导出文件 + +在新会话中输入: +``` +@./.claude-sessions/exports/{timestamp}-{uuid}.md + +继续之前的工作,{描述你要做什么} +``` + +### 方式 3:手动选择性恢复 + +只复制你需要的部分: +- 如果只需要恢复进度:复制"项目进度"部分 +- 如果需要方案细节:复制"实施方案"部分 +- 如果需要决策上下文:复制"关键决策"部分 + +--- + +**导出时间**: {当前时间} +**导出工具**: session-manager v1.0.0 + +🤖 Generated by session-manager plugin +``` + +#### 写入导出文件 + +```bash +# 使用 Write 工具写入 +Write tool: $EXPORT_FILE +``` + +### 6. 展示结果 + +输出格式化的成功信息: + +``` +✅ 会话已成功导出! + +━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ +📄 导出信息 +━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ +会话标题: {标题} +项目名称: {项目名} +会话时间: {开始时间} - {结束时间} +进度状态: {已完成}/{总数} 已完成 + +━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ +📁 文件位置(项目本地) +━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ +导出文件: ./.claude-sessions/exports/{timestamp}-{uuid}.md +文件大小: {文件大小} + +━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ +💡 如何继续工作 +━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + +方式 1(推荐): 在新会话中输入 + + 继续之前的工作:{会话标题} + + @~/.claude/session-exports/{timestamp}-{uuid}.md + + {描述你要继续做的具体工作} + +方式 2: 打开导出文件并复制相关内容 + + cat ~/.claude/session-exports/{timestamp}-{uuid}.md + +━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ +🎯 后续建议行动 +━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + +{列出 2-3 个具体的后续行动建议} +1. {建议1} +2. {建议2} +3. {建议3} + +━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + +🤖 Generated by session-manager plugin +``` + +--- + +## 错误处理 + +### 场景 1: 没有已保存的会话 + +``` +❌ 错误:未找到已保存的会话 + +存储目录: ~/.claude/session-summary/ + +可能原因: +1. 还没有保存过任何会话 +2. 存储目录被删除或移动 +3. 权限问题导致无法访问 + +建议: +- 使用 /session-manager:save 保存当前会话 +- 检查存储目录是否存在:ls -la ~/.claude/session-summary/ +- 检查目录权限 +``` + +### 场景 2: 摘要文件读取失败 + +``` +❌ 错误:无法读取会话摘要文件 + +文件: {文件路径} +错误: {错误信息} + +可能原因: +1. 文件已损坏 +2. 文件权限问题 +3. JSON 格式错误 + +建议: +- 尝试读取其他会话 +- 检查文件完整性:cat {文件路径} +- 如果多个文件都无法读取,可能需要重新保存会话 +``` + +### 场景 3: 搜索无结果 + +``` +ℹ️ 未找到匹配的会话 + +搜索条件: {条件描述} + +建议: +- 尝试使用不同的关键词 +- 检查时间范围是否过窄 +- 查看所有会话:选择"返回会话列表" +``` + +### 场景 4: 导出文件创建失败 + +``` +❌ 错误:无法创建导出文件 + +目标文件: {文件路径} +错误: {错误信息} + +可能原因: +1. 磁盘空间不足 +2. 导出目录不存在或无写入权限 +3. 文件名包含非法字符 + +建议: +- 检查磁盘空间:df -h +- 创建导出目录:mkdir -p ~/.claude/session-exports +- 检查目录权限:ls -ld ~/.claude/session-exports +``` + +--- + +## 交互流程示例 + +### 示例 1: 快速选择最近的会话 + +``` +用户: /session-manager:continue + +系统: 显示最近 10 个会话列表 + +用户: 选择第二个会话 + +系统: ✅ 会话已成功导出! + 导出文件: ~/.claude/session-exports/2025-11-03-16-30-abc123.md +``` + +### 示例 2: 按项目搜索 + +``` +用户: /session-manager:continue + +系统: 显示最近 10 个会话列表 + +用户: 选择"搜索和过滤" + +系统: 显示搜索选项 + +用户: 选择"按项目过滤" + +系统: 显示所有项目列表 + - my-app (3 个会话) + - another-project (5 个会话) + +用户: 选择"my-app" + +系统: 显示 my-app 的 3 个会话 + +用户: 选择第一个 + +系统: ✅ 会话已成功导出! +``` + +### 示例 3: 按关键词搜索 + +``` +用户: /session-manager:continue + +系统: 显示最近 10 个会话列表 + +用户: 选择"搜索和过滤" + +系统: 显示搜索选项 + +用户: 选择"按关键词搜索" + +系统: 请输入搜索关键词 + +用户: 输入"认证"(通过 Other 选项) + +系统: 找到 2 个匹配的会话 + - [2025-11-03] my-app - 实现用户认证功能 + - [2025-11-02] api-service - 添加 JWT 认证 + +用户: 选择第一个 + +系统: ✅ 会话已成功导出! +``` + +--- + +## 跨平台兼容性 + +### 路径处理 +- ✅ 使用 `$HOME` 而非 `~` +- ✅ 使用绝对路径 +- ✅ 使用 `find` 命令递归搜索(标准工具) + +### JSON 处理 +- ✅ 优先使用 Python 3(系统自带) +- ✅ 处理 UTF-8 编码 +- ✅ 使用 `ensure_ascii=False` 保留中文 + +### 时间处理 +- ✅ 解析 ISO 8601 格式 +- ✅ 格式化为本地可读格式 +- ✅ 计算时间范围(今天、本周等) + +### 文件操作 +- ✅ 使用 `mkdir -p` 创建目录 +- ✅ 使用 `date` 生成时间戳 +- ✅ 使用 `cat` 展示文件内容 + +--- + +## 性能优化 + +### 会话列表加载 +- 只读取 summary.json(不读取 details.jsonl) +- 默认只展示最近 10 个(减少交互负担) +- 按需加载更多("查看更多"选项) + +### 搜索性能 +- 在内存中进行搜索(Python 脚本) +- 不使用磁盘索引(保持简单) +- 对于大量会话(>100),可能需要 2-3 秒 + +### 导出文件生成 +- 一次性生成完整内容 +- 不进行额外的文件读取 +- 使用模板字符串拼接 + +--- + +## 使用技巧 + +### 最佳实践 + +1. **定期保存会话** + - 完成重要阶段后立即保存 + - 结束工作前保存当天进度 + +2. **使用清晰的标题** + - 第一条消息描述清楚要做什么 + - 便于后续搜索和识别 + +3. **利用搜索功能** + - 项目较多时,先按项目过滤 + - 记不清时间时,使用关键词搜索 + +4. **选择性恢复** + - 不一定要恢复全部内容 + - 只复制需要的部分到新会话 + +5. **保持存储整洁** + - 定期清理旧会话(手动) + - 备份重要会话 + +### 高级用法 + +**多项目管理**: +```bash +# 在不同项目间快速切换 +cd ~/project-a +/session-manager:continue # 恢复 project-a 的工作 + +cd ~/project-b +/session-manager:continue # 恢复 project-b 的工作 +``` + +**长期项目跟踪**: +```bash +# 每周五保存 +/session-manager:save + +# 下周一恢复,按时间过滤"本周" +/session-manager:continue +→ 选择"按时间范围" → "本周" +``` + +**任务切换**: +```bash +# 紧急任务插入时 +/session-manager:save # 保存当前任务 + +# 完成紧急任务后 +/session-manager:continue # 恢复之前的任务 +``` + +--- + +## 注意事项 + +- ⚠️ 搜索只在摘要数据中进行(不搜索详细日志) +- ⚠️ 导出文件不会自动清理,需要手动管理 +- ⚠️ 大量会话(>50)时,列表加载可能稍慢 +- ⚠️ 导出文件可能包含敏感信息,注意安全 + +--- + +## 未来增强 + +以下功能计划在未来版本中添加: + +- [ ] 会话标签功能 +- [ ] 会话笔记添加 +- [ ] 自动清理旧会话 +- [ ] 导出格式自定义 +- [ ] 会话对比功能 +- [ ] 团队共享支持 + +--- + +🤖 Generated with Claude Code diff --git a/commands/save-session.md b/commands/save-session.md new file mode 100644 index 0000000..6e6422c --- /dev/null +++ b/commands/save-session.md @@ -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 diff --git a/plugin.lock.json b/plugin.lock.json new file mode 100644 index 0000000..6bd63e6 --- /dev/null +++ b/plugin.lock.json @@ -0,0 +1,49 @@ +{ + "$schema": "internal://schemas/plugin.lock.v1.json", + "pluginId": "gh:ChamHerry/claude-code-third-party-plugins:plugins/session-manager", + "normalized": { + "repo": null, + "ref": "refs/tags/v20251128.0", + "commit": "1d4c1cd23672bc042be0c0e11a733d17c7ca0f02", + "treeHash": "1daddc83113d087d7ff028e98b8077dbd163e38dbb2e41034064cbfab61c5214", + "generatedAt": "2025-11-28T10:10:02.053542Z", + "toolVersion": "publish_plugins.py@0.2.0" + }, + "origin": { + "remote": "git@github.com:zhongweili/42plugin-data.git", + "branch": "master", + "commit": "aa1497ed0949fd50e99e70d6324a29c5b34f9390", + "repoRoot": "/Users/zhongweili/projects/openmind/42plugin-data" + }, + "manifest": { + "name": "session-manager", + "description": "会话管理插件 - 智能保存和恢复 Claude Code 会话,支持进度跟踪和工作连续性", + "version": "1.0.0" + }, + "content": { + "files": [ + { + "path": "README.md", + "sha256": "a32a6ada04439fcf8acd030c4f64df0d598a920bcac358cfd48dd54c97b2438a" + }, + { + "path": ".claude-plugin/plugin.json", + "sha256": "17a31f0c06e0473d6e099b2e4efa1b82a363854bd6e1c2826d99fa4dbfb657af" + }, + { + "path": "commands/save-session.md", + "sha256": "aa62129be236dd0b2d4905a6df30d11b621de36fa7d7e2542cd11618bc00857e" + }, + { + "path": "commands/continue-session.md", + "sha256": "16cd433b9c48fbe883cd07b55661187a0f70eff9ebfe147330f719a4d79692d4" + } + ], + "dirSha256": "1daddc83113d087d7ff028e98b8077dbd163e38dbb2e41034064cbfab61c5214" + }, + "security": { + "scannedAt": null, + "scannerVersion": null, + "flags": [] + } +} \ No newline at end of file