关于 end-session
此仓库工作流 Skill 用于结束开发会话,并为后续会话留下可用记录。它按证据更新记忆、问题、待办、文档和工作区状态;删除或丢弃工作前须先征求同意。
主要功能
- 01基于证据复盘会话
- 02更新记忆与问题
- 03跟踪人工后续事项
- 04核对并更新文档
- 05经确认后清理工作区
适用场景
- 01会话结束时记录未完成工作
- 02完成改动后更新问题
- 03检查遗留文件与分支
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ jwh3times/ skills --skill end-session安装后在 Claude Code 中输入/end-session确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
settings/docs.mdhuman-follow-up.mdissue-tracker.mdREADME.mdworkspace.md详细介绍
结束会话
结束本次会话,确保下一次会话能从准确的状态继续,而不必重新梳理。本次会话的持久产出不止是差异:还有它学到的(记忆)、它推进的(议题和看板)、现在需要人工处理的事(后续事项)、现有文档中不再准确的内容,以及它留下的东西(工作区)。按此顺序逐项检查。
开始时宣布:“我正在使用 end-session 技能来结束本次会话。”
在 bash(Windows 上使用 Git Bash)中运行 shell 片段。如果无法使用 gh,请使用等效的 GitHub MCP 操作:缺少 CLI 只会改变接口,不会改变步骤。
此技能将发布工作交给 ship 技能处理:不要更新版本号、添加变更日志章节、推送源代码或创建 PR。已完成的分支应先发布,再运行此技能;尚在进行中的分支则保持原状,并记录当前状态。
始终遵守以下三条规则:
- 以证据为准,而非凭记忆。 某个类别没有内容也是有效结果;如实说明,然后继续。编造记忆、评论或条目,还不如什么都不写。
- 先列出,再删除。 每次删除——文件、分支、工作树、容器——都要先列出,并等待确认。
- 提交或丢弃前先询问,除非设置已预先授权。
0. 设置
此技能会读取 docs/agents/workspace.md、docs/agents/issue-tracker.md、docs/agents/human-follow-up.md 和 docs/agents/docs.md。按照 .agents/skills/end-session/settings/README.md 中的说明读取这些文件,并补全缺失项;相应定义文件就在其旁边。每个 discover: 值在此处解析一次,并在下文复用。
**由交接触发:**当参数中注明 invoked by handoff; document at <path> 时,交接文档已写好并登记。将其路径带入报告,并将用户的工作视为正在另一台机器上继续,而不是在当前检出目录中继续。
1. 盘点
在写入任何内容之前,先确认本次会话做了什么:
git status --short --branch
git branch --show-current
git log --oneline origin/main..HEAD
gh pr list --author @me --state open --json number,title,headRefName
然后运行 Workspace status command。将本次会话产生的内容归入以下类别;每类都会引导后续步骤。
| 类别 | 步骤 |
|---|---|
| 关于如何在此仓库或环境中工作的持久事实 | 2. 记忆 |
| 已开始、完成、受阻、发现或以不同方式理解的工作 | 3. 议题 |
| 现在只有人工才能采取的行动 | 4. 人工后续事项 |
| 文档应记录的决定、发现和状态变更 | 5. 文档 |
| 留下的文件、分支、工作树、容器 | 6. 工作区 |
2. 记忆
记忆保存在仓库之外,每个文件记录一条事实,存放在运行环境的说明中指定的记忆目录里。必须原样使用该路径:根据检出位置推导出的路径会因机器和工具而异;写入错误路径会静默成功,却永远不会被读取。如果运行环境未指定记忆目录,请跳过此步骤并在报告中说明。该目录下的 MEMORY.md 是索引:每条记忆占一行,不写具体内容。
只有在没有这条备注时,新会话在这里就会出错,且仓库中没有现成记录的情况下,才保存候选记忆。AGENTS.md、文档、议题跟踪器、变更日志和 Git 历史都是持久记录;重复记录其中的内容,随着它们变更,记忆也会过时。记忆只用于记录其他地方没有写下的内容:耗费时间的陷阱、用户表达的偏好、尚未定案工作的状态。
- 先读取
MEMORY.md;如有匹配的记忆,应更新它,而不是另建近似条目。 - 更正或删除本次会话证明有误的记忆。
- 使用绝对日期,并用
[[slug]]链接相关记忆;确保MEMORY.md中的每个指针都与文件保持同步。 - 不要在记忆正文中记录尚未修补的安全漏洞;应指明其跟踪记录所在位置。
3. Issue 和看板
Issue 承载工作;Board 承载其状态。标签来自仓库的分流标签词汇表:docs/agents/triage-labels.md,或 docs/agents/issue-tracker.md 中包含该词汇表的部分。
写入看板需要 gh 令牌具有 project 作用域,没有该作用域时会静默失败。检查 gh auth status 中是否有 project(不只是 read:project)。如果缺少,请报告并跳过看板写入;修复命令(gh auth refresh -h github.com -s project)需要真实终端。
从未关闭的 Issue 开始,先查看 Public repository,如果有 Private issue repository,也要查看;始终使用 -R 显式指定:
gh issue list -R <repository> --state open --json number,title,labels \
--jq '[.[] | {number, title, labels: [.labels[].name]}]'
对于本次会话处理过的每个 Issue:
- 已交付 — 评论说明结果,以及对问题的理解发生了哪些变化。PR 合并后关闭 Issue;PR 尚未合并时,保持 Issue 开启并注明 PR。
- 有进展但尚未完成 — 评论说明当前进度和下一项具体步骤,让初次了解情况的读者也能看懂。
- 受阻 — 评论说明阻碍因素,并设置用于记录该情况的
Board fields。 - 理解发生变化 — 更正正文,或评论说明更正内容。描述了错误问题的 Issue 比缺少 Issue 代价更大。
- 新发现的工作 — 按照
New work的说明记录:创建 Issue、添加标签并放入Board;或者创建Board草稿条目(gh project item-create),留待工作得到承诺后转为 Issue。无论采用哪种方式,都要设置看板字段。未进入看板的工作对下一次会话不可见。
安全发现应遵循 Security findings 流程,修复交付前绝不能创建公开 Issue。不得在公开 Issue、PR 和提交中包含私有仓库链接或内容。本次会话未处理的 Issue 留给 triage 技能。
4. 人工跟进事项
对于本次会话已完成工作遗留的每一项必要人工操作,都要执行 .agents/skills/end-session/settings/human-follow-up.md 中的 ## Procedure,包括其他技能(docs-updater、ship)已经启动的事项:应协调这些事项,而不是重复执行。
5. 文档
针对本次会话的工作运行 docs-updater 技能;如果运行环境有子 Agent,就在子 Agent 中运行,并要求其遵循 .agents/skills/docs-updater/SKILL.md;否则自行遵循该文件。子 Agent 无法询问用户,因此要先在此处遵循其第 0 步,完成设置。对于尚未合并的工作使用 fix 模式;对于 ship 已刷新并合并的工作使用 check 模式,并像第 3 步那样,将其报告的任何偏差记录为新工作。对于 ship 报告中需要搜索 Wiki 的已合并工作,还要再运行一次 fix 模式,仅限 Wiki:修复过时引用,而不是将其登记为待办事项。告知它这是 end-session,并将本次会话的发现作为变更清单提供,同时附上差异:决策和发现应根据各自 when 的匹配情况,写入 Doc map 文档,并遵循各文档的标记。对于它返回的任何人工操作,都要运行第 4 步的流程。它的编辑会以未提交状态返回,并纳入第 6 步关于未提交工作的提问。
- 配套仓库。 设置了
Private companion且其工作副本存在时,要从其自身根目录检查:外层仓库的git log、git show和git diff无法查看其内部内容。如果工作副本不存在,请报告无法协调配套文档,且不要在原处创建目录。按照Companion commit policy的说明,将配套仓库的变更作为独立提交提交到配套仓库。 - 变更日志欠账。 本次会话提交的行为变更若没有对应的
Unreleased条目,就属于需要报告的欠账;变更日志由ship编写。 - 统一跟踪渠道。 本次会话添加到代码树中的待办清单、路线图或 TODO 文件会与 Issue 跟踪器重复;应提议将其内容移入 Issue。
6. 工作区
先处理未提交的工作——清理过程中,只有它可能永远丢失:
git status --short
git stash list
如果存在配套仓库,也执行相同操作。对于每项更改,都要询问:在其分支上提交、添加有名称的说明后暂存,还是保留原样。保留原样也是有效选择;请在报告中说明。
分支。 当 PR 在该分支的本地最新提交处或之后合并时,分支即告完成——压缩并合并的提交也适用,此时 git branch --merged 会漏掉所有经过压缩的分支:
git fetch --prune origin
for branch in $(git for-each-ref --format='%(refname:short)' refs/heads | grep -vx main); do
tip=$(git rev-parse "$branch")
pr=$(gh pr list --state all --head "$branch" --json number,state,headRefOid \
--jq 'sort_by(.number) | last | select(.) | "\(.number) \(.state) \(.headRefOid)"')
read -r number state head <<< "$pr"
verdict=unfinished
if [ "$state" = MERGED ]; then
git cat-file -e "$head^{commit}" 2>/dev/null || git fetch -q origin "pull/$number/head"
git merge-base --is-ancestor "$tip" "$head" && verdict=finished
elif [ -z "$number" ] && git merge-base --is-ancestor "$tip" origin/main; then
verdict=finished
fi
echo "$branch ${number:-no-pr} ${state:-none} $verdict"
done
git worktree list
用户同意后,使用 git branch -D 删除已完成的分支(-d 无法删除经过压缩的分支)。有未关闭的 PR、没有 PR 但有自己的提交,或在合并提交之后还有提交的分支,都包含待处理工作:保留该分支;若已准备好发布,请在报告中注明 ship。修剪后仍列出的远程分支也要经过相同检查,然后再执行 git push origin --delete。使用 git worktree remove <path> 移除已完成的工作树,然后执行 git worktree prune。
最后返回 main,在完成下方整理之后执行;如果工作区有未提交的已跟踪更改,或用户准备在当前检出中继续使用此分支,则不要切换。执行 git switch main,然后执行 Sync with main,再执行 docs/agents/workspace.md 中的 Hook: after sync。如果同步无法快进,说明本地 main 有自己的提交:报告这一情况,并保持 main 不变。
文件。 列出 Safe-to-remove paths 和会话遗留在工作区中的零散临时文件,然后按明确路径删除。除非用户明确要求,否则保留 Never-remove paths;像 git clean -x 这样的全量删除命令也会删除这些文件,因此只能按路径删除。
然后:
Dev stack——报告正在运行的内容,并在停止前先询问;数据库可能是有意保持运行的。此处绝不要运行其 Never run 命令。Generated-config check——适用且报告存在偏差时,重新生成并提交两边的内容。- 执行
docs/agents/workspace.md中的Hook: end-session cleanup。 - 最后执行
Final portability check。准确说明每个仓库的状态,不要笼统地说检出状态已同步。
7. 报告
最后简要、如实地说明:
- 添加、更新或删除的记忆,以及每项的一句话原因。
- 已评论、关闭、添加标签或创建的问题,按编号列出。
- 人工跟进事项:已验证的问题和 Wiki 链接、哪些内容尚未发布及原因,或者说明没有剩余事项。
- 已更新的文档;配套仓库中的更改及其提交状态,或说明配套仓库不存在。
- 步骤 0 中写入的设置文件。
- 工作区:删除了什么,刻意保留了什么及其原因。
- 仍未解决: 未提交的更改、未推送的分支、等待审核的 PR、正在运行的容器、待用户决定的事项;如果通过移交调用此技能,还要包括移交文档的路径。
明确说明哪些事情尚未完成。准确地说“这三项仍未解决”,正是此技能的目的。