mcpField
H
handoff

handoff

github.com/davepoonAgent 工作流3.7k61 次安装1 天前更新
代码仓库

关于 handoff

`/handoff` 是用于结束会话时保存工作上下文的技能。它通过 MCP 记录独立记忆,并写入叙述式会话日志和当前项目状态文件。

主要功能

  1. 01逐条记录决策与经验
  2. 02预览待确认的记录
  3. 03写入叙述式会话日志
  4. 04更新项目状态和时间戳
  5. 05在条件允许时提交 `~/.origin/` 更改

适用场景

  1. 01结束会话前保存项目上下文
  2. 02记录决策和技术经验
  3. 03跟踪进行中与待处理工作
  4. 04查看尚未确认的记录

MCP 相关

该技能通过 MCP 列出待处理的记忆记录,并将决策、经验和其他值得保留的信息逐条存储。

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/davepoon/buildwithclaude --skill handoff

安装后在 Claude Code 中输入/handoff确认已加载。

详细介绍

/handoff

会话结束回顾。每次交接都要生成 3 项内容:

  1. 粒度化 MCP 记录 — 每项决策、经验或易错点各记录一条(数据库为权威来源)。
  2. 会话日志 md — 位于 ~/.origin/sessions/<YYYY-MM-DD-HHmm>-<slug>.md 的叙述线索。
  3. 项目状态 md + json — 当前目标 + 上次交接时间戳,位于 ~/.origin/sessions/_status/。

这 3 项各自独立:记录是可查询的原子信息,会话日志是叙述线索,状态文件让下一次会话知道我们上次进行到了哪里。

步骤

1. 检测项目和上次交接时间
Bash: cd_repo=$(git -C "$PWD" rev-parse --show-toplevel 2>/dev/null); echo "${cd_repo:-no-git}"
  • 如果输出是路径 → 将其 basename 作为 <project>(例如 origin)。
  • 如果输出为 no-git → 使用 cwd 的 basename。跳过以下 git 步骤,完全依赖对话上下文。

读取 ~/.origin/sessions/_status/handoff-<project>.json 中的 lastHandoff 时间戳(ISO-8601)。如果文件不存在,默认使用“12 小时前”。

1.5 待确认记录预览

确定 <lastHandoff> 后,调用:

list_pending(limit=50)

MCP 会返回包含 source_id、content、created_at 和其他元数据的记忆行。将 lastHandoff(ISO-8601 字符串,例如 2026-05-13T22:50:00Z)转换为 Unix 纪元秒整数,然后再进行筛选:

Bash: date -j -f %Y-%m-%dT%H:%M:%SZ "$lastHandoff" +%s

也可以使用你选择的脚本语言(Python 的 datetime.fromisoformat、 JavaScript 的 Date.parse 等)。将结果保存为 lastHandoffEpoch。

然后筛选响应行:保留 row.created_at >= lastHandoffEpoch 的行。 这些是本次会话产生、但质量门禁未确认的记录(不可信来源记录)。

如果筛选结果为空,不要输出任何内容。继续执行步骤 2。

如果结果非空,在现有记录流程之前渲染一次预览块:

Pending captures this session (<N> total, top 3 shown):

1. mem_xyz789  "..."  (untrusted source: <agent>)
2. ...

Default: proceed (captures stay pending). Opt in by running
`/review captures` before re-invoking /handoff if you want to walk them.

不要在行内提示用户对每项采取操作。无论如何,用户都会继续执行 /handoff;预览仅供参考。

2. 收集会话上下文(仅在 git 仓库中并行执行)
Bash: git -C <repo> log --oneline --since=<lastHandoff>
Bash: git -C <repo> status --short
Bash: git -C <repo> diff --stat HEAD~5..HEAD 2>/dev/null
Bash: git -C <repo> worktree list

捕获输出。结合对话历史推断发生了什么。如果不是 git 仓库,则跳过——以对话上下文为准。

3. 推断,不要提问

根据 git 输出和对话内容静默归纳。将每项归入面向用户的类别。每个类别对应捕获调用中的 daemon memory_type:

显示标签daemon memory_type内容范围
决策decision架构选择、工具或模式选择(附带原因)
经验lesson发现的根本原因、找到的解决方法、技术见解
见解gotcha意外行为、调试发现、容易踩坑的地方
更正preference用户提出异议、纠正做法或假设
事实fact值得留存的持久项目、人员或工具事实

非记忆类事项(不存储,仅写入会话日志):

  • 未完成事项 — 已启动但尚未完成的工作、阻碍因素。

跳过 git 中已有的纯机械事实(文件路径、函数名、配置值)。提交日志会保留这些信息。

4. MCP 记录(每项一条)

对每项重要内容,使用对应的 memory_type 调用:

capture(content="<one self-contained sentence with WHY>", memory_type="<decision|lesson|gotcha|preference|fact>")

保持原子性:每次调用记录一项决策。不要将多项内容合并为一条记忆。daemon 会与现有知识去重,因此重复存储已知事实不会产生任何影响。

仅当符合以下任一条件时,才在存储前向用户展示内容:

  • 与现有记忆矛盾(召回结果中存在冲突事实)。
  • 涉及重大事件、不可逆操作或生产环境变更。
  • 无法确定该内容是长期有效还是暂时性的。

其他情况只需存储,并在最后汇报数量。

5. 编写会话日志

使用 Bash heredoc 写入 ~/.origin/sessions/<YYYY-MM-DD-HHmm>-<slug>.md:

# Session <YYYY-MM-DD HH:MM> — <slug>

**Project:** <project>
**Range:** <lastHandoff> → <now>

## Accomplished
- <item>

## Decisions
- <decision and rationale>

## Lessons & Gotchas
- <root cause / workaround>

## Open Threads
- <what's unfinished>

## Captures stored
- <source_id_or_brief_summary>

## Git summary
<git log --oneline output>

<slug> = kebab-case 格式的 2–4 个词摘要(session-handoff-md-writer)。

6. 更新项目状态

覆盖 ~/.origin/sessions/_status/<project>.md:

# <Project> — Current Status

## Last session (<date>)
- <accomplished bullet>

## Active

- <item> (added <YYYY-MM-DD>)
- <blocked item> (added <YYYY-MM-DD>) (gated: <trigger>)

## Backlog

- <item> (added <YYYY-MM-DD>)

每个项目一个文件。新会话会覆盖旧内容——这里记录的是当前状态,而不是日志。

分成两个部分,而不是一个平铺列表: ## Active 和 ## Backlog 用于区分两类任务,避免它们混在一起。Active = 值得接下来处理的新近动态。Backlog = 较早搁置的事项,保留作参考,但不纳入“接下来做什么?”的考虑范围。

每条项目符号都加上日期标记,格式为 (added <YYYY-MM-DD>)。添加新事项时使用今天的日期;延续事项时保留原始日期。日期能让人一眼看出事项的存续时间,也避免相对时间不断变化。

受阻事项在行内加标签,格式为 (gated: <trigger>)——不单独设一个部分。标签说明事项为何暂时无法推进;项目符号仍放在反映其新近程度的部分中。

升格 / 降级规则:

  • 本次会话中的新事项 → 移至 ## Active,并标注今天的日期
  • ## Active 中本次会话未处理、且上次会话也未处理的事项 → 降至 ## Backlog(保留原始日期)
  • ## Backlog 中已恢复处理的事项 → 升回 ## Active(保留原始日期——陈旧程度取决于事项本身,而不是项目符号文本)
7. 写入时间戳

覆盖 ~/.origin/sessions/_status/handoff-<project>.json:

{
  "lastHandoff": "<ISO-8601 now>",
  "project": "<project>",
  "summary": "<one-line>"
}

每个项目单独存储文件,避免并行会话相互覆盖。

8. 自动提交 ~/.origin/

写入上述文件后,保存此次变更快照,方便用户通过 git log 查看记忆的时间线。此操作具有防护机制——若缺少 git 或 ~/.origin/ 尚未成为仓库,则静默跳过。

Bash: git -C ~/.origin add -A && \
      git -C ~/.origin -c user.name=Origin -c [email protected] \
          commit --quiet -m "session: <slug>" 2>/dev/null || \
      (sleep 1 && git -C ~/.origin add -A && \
       git -C ~/.origin -c user.name=Origin -c [email protected] \
           commit --quiet -m "session: <slug>" 2>/dev/null) || true

重试机制可应对 index.lock 竞争——守护进程可能恰好在同一时刻写入 ~/.origin/(捕获内容时自动提交)。等待一秒足以让守护进程释放锁。

9. 确认

输出一个摘要块,按显示标签分组列出捕获内容:

Handoff stored.
  Decisions:   <N> (brief list)
  Lessons:     <N> (brief list)
  Insights:    <N> (brief list)
  Corrections: <N> (brief list)
  Facts:       <N> (brief list)
  Session:     ~/.origin/sessions/<filename>
  Status:      ~/.origin/sessions/_status/<project>.md
  Git:         <commit hash> session: <slug>

仅在标签下有内容时显示该标签。将条目写成简短短语,而非完整句子——会话日志中已有详细信息。

使用时机

  • “收尾吧”、“就到这里吧”、“我们完成了”。
  • 会话即将结束,否则有用的状态会丢失。

不要使用的情况

  • 工作过程中途捕获 → 使用 /capture(单条记忆)。
  • 搜索 / 查找 → 使用 /recall。
  • 没有决定或经验教训的一次性聊天——仅捕获内容即可。

关于三类产物的说明

  • 记忆(MCP 捕获内容)仅存储在守护进程数据库中。确认操作会切换 stability 标记——它们永远不会导出到 md 文件。
  • 页面是知识库风格的综合内容,由守护进程在运行 /distill 时写入 ~/.origin/pages/。引用会链接回源记忆 ID。
  • 会话(本技能)仅存储在 ~/.origin/sessions/。它们是叙事主线:按时间顺序组织,而非按主题组织。可将其作为工作的变更日志来浏览。

评论

支持 Markdown