关闭会话与收尾
项目中积累了多个并行会话:有些已完成,有些在等待所有者,有些留下了未提交的代码、分支、工作副本以及“以后再说”的发现。目标是将其整理成所有者可以关闭所有多余内容且不会丢失任何信息的状态。
你是唯一处理此事的会话(编排者)。从现在开始,一切通过你进行:其他会话向你提交工作,你向所有者提问,他不再进入他们的窗口。
预期成果
- 关闭文件放在项目中,第一部分是一个一屏的“现在”页面。
- 每个结果都在 git 中(有自己的提交,已合并或明确标记为未合并),或者直接说明“在 git 之外,没有副本”。
- “待所有者处理”列表——按重要性编号,附带现成的命令。
- 一个发现队列,而不是新的会话和卡片。
- 多余的会话归档;打开的会话按名称列出,附有原因和关闭条件。
- 项目看板、状态文档和记忆与事实相符。
规则
每条规则都源于实际错误;具体案例参见 references/lessons.md。
- 事实是命令的输出。“已提交”、“已合并”、“已部署”、“检查通过”都来自 git 和实际运行结果,而不是来自会话报告或你对自己一小时前记忆的描述。来自会话报告的数字应注明“根据会话报告”。
- 什么可以不经所有者同意,什么需要经过同意。
- 不经同意: 读取;维护关闭文件;将临时文件夹中的有用内容复制到项目中(不覆盖任何内容)。
- 在首次报告(步骤 3)之后,在原始请求范围内: 修改看板、状态文档和记忆,使其与事实一致。
- 仅经同意: 提交、合并、删除分支、副本或标签、推送到服务器、部署到测试环境、归档会话、移动和重命名所有者运行包和脚本的位置。 “提交”不意味着“推送”;“合并”不意味着“删除副本”。
- 所有者给出的指令可以有“范围” ——针对可见操作:例如“已提交的会话按提交顺序关闭”、“将已提交的工作提交到其分支”。将其逐字记录在“现在”页面上,不要扩展到相邻操作。
- 所有者的话——是他写在你窗口里的内容。 其他会话转述的话是该会话的报告:对其本身是授权,对你不是。
- 会话数量不会增加。 被关闭的会话几乎总会发现新的缺陷并创建卡片,然后所有者运行它们——到清理结束时,会话数量比开始时还多。立即与所有者达成一致:不运行卡片,发现以行形式加入队列。并告诉其他会话这一点(使用“新秩序”模板)。
- 在执行任何修改操作之前,重新读取状态。 所有者经常同时对你和另一个会话给出相同的指令。在提交前——运行
git log -3、git status、查看索引;在编辑公共文件前——检查它一分钟前是否被修改过。 - 不要绕过他人的限制。 写入生产服务器以及任何被权限检查阻止或可能阻止的操作,都由所有者完成。不要寻找变通办法,也不要将其委托给其他会话——这同样是变通。
- 显著结果不由执行者验证。 合并、部署包、生产脚本——由接手结果的单独执行者验证,而不是你的结论。
- 获得费用批准。 检查数十个会话涉及大量执行者。如果你知道所有者有关于费用的规定(请查看他的 CLAUDE.md),在开始前说明规模。
流程
步骤 0. 框架
在阅读会话日志之前,确定四件事;在步骤 3 中将其记录在关闭文件的“框架”部分。
- 什么被认为是项目。 项目文件夹以及其会话工作过的所有仓库,包括位于其他文件夹中的仓库。如何找到它们:
使用
repo_state.py <项目文件夹>列出没有 git 的文件夹内的仓库; 使用sessions.py list显示每个会话访问过的文件夹和仓库(通过git -C)。将列表用一行向所有者确认。 - 状态在哪里。 看板或编排日志、状态文档、记忆。如果没有看板,则关闭文件将成为看板。不要完整读取大型看板:通过搜索名称来查找规则部分和与相关会话相关的条目。
- 哪些会话不要动。 定时和提醒会话(在
list中标记为“计划”)、其他项目的会话、下一阶段需要的会话、以及你自己。 - 所有者已给定的指令: 提交、推送、生产、测试环境、费用。它们存在于 CLAUDE.md、看板和记忆中——要阅读它们,不要凭记忆转述。
步骤 1. 清单(只读)
脚本位于此技能的 scripts/ 目录中,且只进行读取操作。从项目文件夹(或使用 --root <项目文件夹>)运行它们。命令中的技能文件夹路径由 Claude Code 填充:技能的安装方式有多种(个人文件夹、项目文件夹、插件),所以不要凭记忆写入路径。如果路径未被填充(命令中有美元符号和大括号),则从技能开头的“此技能的基本目录”行获取文件夹。
python3 -B "${CLAUDE_SKILL_DIR}/scripts/sessions.py" list --days 14
python3 -B "${CLAUDE_SKILL_DIR}/scripts/repo_state.py" <仓库> <仓库>
python3 -B "${CLAUDE_SKILL_DIR}/scripts/sessions.py" scratch
python3 -B "${CLAUDE_SKILL_DIR}/scripts/sessions.py" cards --days 14
- 按日志查看会话——
list:日志如何结束、所有者何时写入、会话在哪些文件夹和仓库中工作。添加--project <路径或文件夹名称>可以包含相邻仓库的日志。日志不知道会话是否已存档或仍在运行。 - 在应用程序中查看会话——
mcp__ccd_session_mgmt__list_sessions。应用程序的工具可能被延迟加载:通过 ToolSearch 加载它们 (select:mcp__ccd_session_mgmt__list_sessions,mcp__ccd_session_mgmt__archive_session,SendMessage,ListAgents),否则你会认为它们不存在。设置一个有充足余量的limit(默认是 20),要统计已存档的则设置include_archived: true。响应中包含所有项目的会话——根据文件夹筛选;当前会话不在响应中。应用程序中的会话 ID (local_…) 不等于日志 ID:根据名称匹配。如果没有工具,请向所有者请求列表快照。 - 仓库——
repo_state.py:未提交的文件、被忽略的文件、未合并的分支、工作副本是否干净、stash、未推送的提交、未完成的操作。 - 临时文件夹——
scratch:系统清理时会消失的内容(并非归档时,而是无预警地)。 - 卡片——
cards:会话创建了哪些卡片,其中哪些尚未运行。未运行的进入发现队列。“已运行但没有日志”意味着会话转移到了另一个项目:使用--project添加它。
共享资源(测试环境、锁、测试数据)——单独一行:锁是否空闲,是否遗留了其他人的临时数据。
步骤 2. 检查每个会话
针对每个会话,回答相同的问题并填入表格(references/templates.md):
| 问题 | 如何验证 |
|---|---|
| 它做了什么,结果在哪里 | 仓库、分支、哈希、文件 |
| 是否已提交 | git status 其工作副本——应该为空 |
| 是否已合并 | git merge-base --is-ancestor <分支> <主分支> |
| 结果是否已记录 | 读取项目文档、看板、记忆 |
| 在等待所有者做什么 | 其最后几条消息 + 此后是否有关闭 |
| 是否有“之后再做…”的承诺 | 日志末尾 |
| 其临时文件夹中有什么 | sessions.py scratch |
日志末尾:sessions.py tail "<名称的一部分>" --last 40。最后三条回复完整显示,其余的中间部分被截断;要完整显示请使用 --chars 0。从会话的最终消息、包含“文件夹”和“通过 git -C 工作”的行以及工作进度(--tools)中获取会话的工作副本和分支:日志中的分支字段通常为空。
标签:所有者——由人在该窗口中写入;卡片——由卡片启动的会话的第一条消息:文本由另一个会话写入,而不是所有者;会话——另一个会话的消息;计划——自动启动。输出中没有所有者的词并不证明其不存在:日志压缩后,词汇被转述。
判决来自以下五种之一:
- 立即关闭——已交付;结果在 git 中或标记为“在 git 之外,没有副本”;所有等待所有者的内容都已转移到“待所有者处理”列表,并且会话本身不再需要;
- 在某个操作后关闭——指定一个操作及其所有者;
- 保留——正在工作或将来需要;说明原因和关闭条件;
- 不要动——计划和外部项目;
- 已存档——仅检查其临时文件夹、工作副本和未提交的内容。
如果会话超过十个,存在 Workflow 工具,且所有者同意并行检查,则运行 ${CLAUDE_SKILL_DIR}/references/audit-workflow.js(按组读取器、单独的存储位置验证、摘要;参数在文件开头描述,将 ${CLAUDE_SKILL_DIR} 传递给 skill)。否则,你自己用相同的问题列表进行检查。
此步骤的陷阱:
- 没有自己提交的分支并不意味着“已合并”:没有提交的工作的分支以及刚刚开始的新会话的分支也是如此。
- 分支已不存在(git 返回代码 128)——这不意味着“未合并”:需根据日志末尾检查其顶点的哈希。
- 在日志中间说“完成”的会话可能在之后发现了自己工作中的缺陷。阅读结尾,而不是第一个“完成”。
- 没有对照实验的会话诊断是猜测。不要将其作为原因转移到文档中。
步骤 3. 关闭文件和首次报告
文件——关闭_会话_<YYYY-MM-DD>.md 放在看板旁边(框架见 references/templates.md)。如果该日期的文件已存在——不要创建新文件或覆盖它:读取它,只重写“现在”部分,将以前的内容移至其下的日志中。在 git 项目中,该文件在所有者同意之前保持未提交状态——在“不在 git 中的内容”部分中提及它。
第一部分是**“现在”页面**:这一切的目的是什么,当前规则是什么,已完成什么,哪些内容在 git 中,哪些会话已打开,收到了哪些所有者的指令以及已执行了什么,哪些需要他自己运行,发现队列。下面是表格和日志。
每次事件后重写“现在”页面,而不是在底部追加:所有者在迷失方向时会读取它。每次编辑时,更新时间标题,重新计算列表中的数字,并重新读取决策块——“正在进行中”和“等待中”不应在事情完成后仍保留。
然后向所有者报告:可以立即关闭多少个会话,在某个操作后可以关闭多少个,哪些内容不在 git 中,以及正在等待他处理什么。在第一次报告中,询问所有者的指令——否则你必须逐个会话询问:
- 是否在已交付的会话交付时关闭它们;
- 是否将已交付的工作提交到其分支而无需单独询问;
- 他是否确认正在关闭的会话的卡片不会运行。
问题格式见“与所有者对话”部分。
步骤 4. 收尾
此顺序确保不会丢失任何内容:保存 → 提交 → (归档会话,步骤 5) → 合并 → 清理。
- 将临时文件夹中的材料保存到项目中:检查协议、之前状态的快照、预演。将其放在结果旁边。如果目标文件夹在
.gitignore中(repo_state.py会显示它,行“被忽略”)——将其添加到“不在 git 中的内容”部分:保存到项目中并不意味着保存到 git 中。 - 提交已完成的工作——每个工作到其自己的分支,使用显式路径。提交前检查要添加的内容中是否有密钥、密码和个人数据。包含多个会话片段的文件,通过索引按会话拆分开来,不要触及工作文件。使用单独的分支来测试提交。配方见
references/git-recipes.md。 - 合并——根据所有者的指令,在合并前记录旧顶点的哈希。在合并结果上运行检查,而不是单独在分支上:三个单独通过的分支在一起可能导致失败。
- 删除副本和分支——仅在验证后:主历史记录包含分支工作的提交;副本干净;其包含协议的被忽略文件夹已处理;没有打开的会话在该副本中工作。
git branch -d对于未合并的分支会失败,但会静默删除没有自己提交的分支——包括活动会话的新分支。不要删除相邻项目会话的分支和副本:标记“由该项目处理”。 - 部署到测试环境,如果所有者指定——按照测试环境规则(锁、邻居、前后的邻居检查)。
- 对于生产环境——仅准备。 一个包含计划、应用和回滚以及独立验证的脚本,以及“待所有者处理”列表中的一行,包含确切的命令。以前位于所有者运行位置的包或脚本的旧版本是危险的:立即告诉所有者“不要运行旧版本”,并在得到他的许可后将其移动到“已过时——不要运行”子文件夹中,并附上说明。如果发现已告诉所有者的命令中存在缺陷——首先告诉他“在收到我的消息之前不要运行”。
- 修复文档和记忆。 版本、分支顶点、“未合并”、“等待中”——与事实保持一致。只将持久性信息(规则、陷阱、内容位置)写入记忆;当天的状态写入项目文件。
- 发现加入队列。 一条记录:是什么、在哪里、如何确认、有什么风险、需要什么来修复。
在会话仍处于打开状态并正在编辑相同文件时,告诉它“稍等”并等待响应:投递并不意味着消息已被阅读。在你提交后,说“树现在空闲”。如果你正在检查一个包,而该会话可能重新构建它,请它不要碰它,并在检查前后比较校验和。
步骤 5. 关闭会话
一旦已交付的会话的材料已保存并且工作已提交到其分支,就将其归档——它不需要等待合并和副本清理。存档是可逆的 (unarchive_session),删除不是;使用存档。
在归档每个会话之前:
- 其工作副本干净,包含协议的被忽略文件夹已处理。根据工具描述,归档默认会删除应用程序为会话创建的工作副本;会话自己通过
git worktree add创建的副本会保留——你(步骤 4,第 4 点)负责删除它们; - 其临时文件夹已处理——在表格中标记此信息;
- 日志末尾没有承诺和未..。