关于 handoff
handoff 是用于将开发会话交接到另一台机器的技能,面向需要跨设备继续工作的开发者。它编写交接文档、维护活动交接映射,并检查尚未合并或推送的工作。
主要功能
- 01编写供另一台机器接手的文档
- 02维护项目活动交接映射
- 03审查未合并及本地工作
- 04同步交接文档与映射
- 05提示后续运行 lets-go
适用场景
- 01在另一台机器继续开发会话
- 02记录项目状态和后续步骤
- 03发现尚未推送的本地改动
- 04管理同一项目的交接文档
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ jwh3times/ skills --skill handoff安装后在 Claude Code 中输入/handoff确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
handoff-map.mjsLICENSEmachine-config.mdagents/openai.yamlsettings/handoffs.mdREADME.mdworkspace.md详细介绍
交接
只有两样东西能到达另一台机器:GitHub 上的内容和 Handoffs 文件夹里的内容。交接文档记录对话;其旁边的 handoff_map.json 列出每个项目的当前交接文档,lets-go 技能会在另一台机器上继续处理该文档,然后将其清除。未合并工作提醒会找出原本会留在这台机器上的内容。
开始时声明:“我正在使用 handoff 技能交接本次会话。”
在 bash 中运行 shell 代码片段(Windows 上使用 Git Bash)。只能通过 node .agents/skills/handoff/handoff-map.mjs 读取和写入映射文件,绝不能手动操作:所有机器上的每个代码库都共用该文件。每条命令都会输出 JSON;当这台机器的传输方式需要时,还会自行将文件移入或移出云端。
用户传入参数时,这些参数说明了下一次会话的用途:围绕该用途来组织文档。
0. 设置
- **代码库:**此技能会读取
docs/agents/handoffs.md和docs/agents/workspace.md。按照.agents/skills/handoff/settings/README.md的说明读取这些文件,并补齐缺失内容;定义文件就在其旁边。 - **机器:**按照
.agents/skills/handoff/machine-config.md操作,直到config显示configured: true。如果无法配置 Handoffs 文件夹,则将文档写入操作系统临时目录,告知用户该文档不会到达另一台机器,并在步骤 2 后停止:完成收尾会留下无人能接手的交接内容。
1. 检查未合并的工作——并发出提醒
任何不在 origin/main 上的内容,除非至少已推送,否则另一台机器都看不到:
git fetch origin --prune
git status --porcelain --untracked-files=all
git stash list
git worktree list
git for-each-ref refs/heads --format='%(refname:short) %(upstream:short) %(upstream:track)'
git branch --no-merged origin/main
git branch -r --no-merged origin/main
gh pr list --author @me --state open --json number,title,headRefName,url
然后运行 Workspace status command,在每个额外工作树中运行 git status --porcelain;如果已检出 Private companion,还要运行 git -C <companion> status --porcelain 和 git -C <companion> log --oneline @{u}..HEAD。
--no-merged 会把 squash 合并的分支也列出来。对它列出的每个分支,运行 gh pr list --state merged --head <branch> --json number,headRefOid:如果该分支的最新提交是已合并 PR 的 headRefOid,或是其祖先(git merge-base --is-ancestor <branch> <headRefOid>),则其工作已进入 main;将其排除。
将剩余内容分为两组:
- 仅本地——另一台机器看不到:未提交或未跟踪的更改、暂存内容、未推送的提交、没有上游的分支,以及伴随代码库中的同类内容。
- 已推送,未合并——可以访问,但尚未进入
main:已推送的分支和未关闭的 PR。
如果任一组中有内容,请立即提醒用户,在撰写文档之前使用标题 ⚠ Work not merged to main:每项单独一行,列出其代码库、分支或路径,以及所属组。明确说明,仅本地的工作不会到达另一台机器,除非将其推送,并询问是否要推送;对于已完成的分支,可建议使用 ship 技能。提醒仅用于告知,不会阻止后续操作:无论用户如何回应,都继续执行。如果没有需要报告的内容,请说:“所有工作都在 origin/main 上。”
2. 编写文档
node .agents/skills/handoff/handoff-map.mjs get --key <Map key>
conflicts不为空——继续之前,询问用户当前应以哪份地图副本为准。file不为 null——此仓库有一份较早的交接文档,从未被接手。阅读它,延续仍然有效的内容,并在报告中将其注明为已被取代。将文件留在原处。
选择文件名(如果用户提供了参数,则传入 --topic <slug>):
node .agents/skills/handoff/handoff-map.mjs name --key <Map key>
将文档直接写入它打印出的 path,供另一台机器上的初次阅读者阅读。按以下顺序组织章节:
- 当前位置——推送完成后,仓库、分支、
origin/main提交、最新发布标签、工作树以及 companion 的状态。 - 未合并的工作——原样列出步骤 1 的内容,或写“无——所有内容均已在
origin/main上。” - 本次会话完成的工作——列出结果及其记录(PR、issue、提交),而非过程叙述。
- 后续步骤——具体且按顺序排列;第一步必须可以立即开始,无需询问。
- 待定决策——用户仍需决定的事项。
- 本机知识——Agent 记忆和会话临时记录仅保留在这台机器上:写出后续步骤所需的事实和注意事项。
- 建议的技能——下一位 Agent 应调用哪些技能,以及在哪一步调用。
补充 Extra document content 中列出的所有内容。对于其他记录中已有的内容——规范、ADR、issue、PR、提交、差异——只通过路径或 URL 引用,不要重复陈述。文档会离开仓库,存放在个人云盘中:将主目录写作 <home>;省略机密、令牌、密码和个人数据;通过链接引用 companion 内容和私有 issue,不要摘录其内容。
重新读取文件并确认整篇文档都在其中,即表示此步骤完成。
3. 标记为活动文档
node .agents/skills/handoff/handoff-map.mjs set <file> --key <Map key>
在 CLI 镜像上,此操作会推送文档、拉取最新地图、写入此仓库的条目、推送地图,并重新读取云端副本;如果期间有另一会话写入,则会重试。当输出中的 current 为 <file> 时,即表示完成(在 CLI 镜像上,verified 还必须为 cloud)。如果 previous 不为 null 且不等于 <file>,则表示存在已被取代的交接文档:保留在文件夹中,并在报告中注明。
4. 使用 end-session 收尾
调用 end-session 技能,并传入参数 invoked by handoff; document at <path>。如果执行环境无法调用技能,则阅读 .agents/skills/end-session/SKILL.md 并按其中指示操作。工作会在另一台机器上继续,因此 end-session 可以将此工作区恢复到 main;其他审批关卡仍然适用。
如果 end-session 更改了文档中陈述的事实——推送或提交了工作、关闭或新建了 issue、删除了分支或工作树,或用户解决了待定决策——则编辑文档以反映实际情况,然后发送新版本(不含地图):
node .agents/skills/handoff/handoff-map.mjs push <file>
end-session 完成后,文档中的 当前位置 和 未合并的工作 各项均属实,即表示文档完成。
5. 报告
- 文档路径,以及当前指向该文档的地图条目(
previous→current)。 - end-session 自身的报告。
- 最后再次运行步骤 1 的审计,使其在漫长的收尾过程中仍保持最新:列出当前的
⚠ Work not merged to main,或写“没有未合并的工作——另一台机器可以从origin/main开始。” - 提醒:在另一台机器上对此仓库运行
lets-go技能。同步文件夹会在大约一分钟内送达文档;在 CLI 镜像上,文档已经在云端。