SuperAPI AI 工具集

handoff

办公与效率

查看项目

更新于 10-15 09:44

技能介绍

handoff 是一个会话结束交接记录工具(Session-End Handoff Writer),用于在会话结束时更新 HANDOFF.yaml,记录已完成的工作、新发现的缺口以及当前项目状态。

用途

HANDOFF.yaml 分为两部分:items 是仍待处理工作的短期上下文层,log 是已完成工作的持久单行历史。GitHub issues 通过 valerie 和 doob 协调,是活动工作的真实来源。非 Valerie 技能应通过 handoff-db 使用本地 SQLite 数据库加 HANDOFF YAML,绝不直接使用 doob。从 HANDOFF 到 backlog 的脚本化桥接是 handoff-reconcile,应使用它而不是手工重建 doob 命令。项目状态(构建、测试、分支)单独存放在 .ctx/HANDOFF.<name>.<base>.state.yaml 中——生成文件,从不提交。渲染的参考文档也会写入 .ctx/HANDOFF.md。

文件发现

使用 handoff-detect 解析 HANDOFF.yaml 路径(如果可用):

handoff-detect # 存在则返回路径,不存在则返回预期路径并以退出码 2 结束 handoff-detect --name # 仅返回预期文件名(例如 HANDOFF.devkit.devkit.yaml) handoff-detect --root # 仓库根目录 handoff-detect --project # 项目名称

如果 handoff-detect 不在 PATH 中,则回退到在仓库根目录用 glob 匹配 HANDOFF.*.yaml。

旧版回退(只读):如果不存在 HANDOFF.yaml 且仓库根目录存在 HANDOFF.md,则将其作为自由格式读取。除非被要求,否则不要转换。

步骤

  1. 获取当前状态

git branch --show-current git log --oneline -5 cargo check 2>&1 | tail -3 # 或对应语言 cargo test 2>&1 | tail -5

  1. 读取现有 HANDOFF.yaml 和 .ctx/HANDOFF...state.yaml(如果存在)

  2. 更新 HANDOFF.yaml

items——应用不可变性规则(见 references/schema.md):

新缺口 → 以新 id 追加

已完成或上游关闭 → 在 log 中记录结果后从 items 中移除该项

阻塞 → 设置 status: blocked,追加一条 type: blocker 的额外条目

不要编辑现有条目的 title、description、priority 或 files

不要在已提交的 items 中保留 done 或 parked 条目

human-edit 确认——对于本次会话中由 handoff 呈现的任何没有 reviewed 字段的 type: human-edit 额外条目,为该条目添加 reviewed: <today>。

log——前置一条新条目(最新在前)。此部分持久,非临时。必填字段和格式:

date:会话结束时的 ISO 8601 日期时间——date +%Y%m%d.%H%M%S——绝不用裸日期

session:从上一 log 条目的 session 值递增(如果没有先前 log 则从 1 开始)

claude_session_id:如果设置了 $CLAUDE_SESSION_ID 环境变量则从中捕获;未设置则省略该字段

summary:一行,过去时

commits:每个提交使用 {sha, branch} 对象形式——绝不用裸哈希字符串:

commits:

  • sha: abc1234 branch: main

updated——设置为当前 UTC 日期时间:date +%Y%m%d.%H%M%S。

  1. 写入 HANDOFF.yaml

输出干净的 YAML。无锚点,无别名。

  1. 写入 .ctx/HANDOFF...state.yaml

如果 .ctx/ 不存在则创建。用步骤 1 的当前状态完全覆盖。

从会话开始以来的提交中更改的文件填充 touched_files。如果会话边界不清晰,使用自 HANDOFF.yaml 中最后一条 log 条目日期以来更改的文件:

git diff --name-only $(git log --format="%H" --since="<last-log-date>" | tail -1)..HEAD

如果为空则省略该字段。

  1. 同步到 SQLite

运行 handoff-db(通过插件的 bin/ 在 PATH 中可用):

handoff-db upsert --project <project> --handoff <path-to-HANDOFF.yaml>

如果脚本未找到或退出非零,跳过并在输出中注明。

不要从此技能调用 doob。valerie 拥有 doob 和 GitHub issue 同步。

6b. 将打开的 HANDOFF 条目协调到 backlog

运行脚本化的 Valerie 桥接:

handoff-reconcile sync --project <project> --handoff <path-to-HANDOFF.yaml>

这是必需的。在通过此命令将每个打开或阻塞的 HANDOFF 条目协调到配置的 doob 后端之前,handoff 更新不算完成。除非你在调试协调器本身,否则不要用临时的 doob todo add / doob todo list 命令重建此流程。

如果脚本未找到或退出非零,停止并报告失败,而不是静默继续。

  1. 生成 .ctx/HANDOFF.md 和 .ctx/HANDOVER.md

运行辅助脚本一步写入两个渲染文档:

generate-ctx-docs
--handoff <path-to-HANDOFF.yaml>
--state <path-to-HANDOFF.state.yaml>
--ctx <repo-root>/.ctx

generate-ctx-docs 通过插件的 bin/ 在 PATH 中可用。它优先使用 nu(如果存在),回退到 POSIX sh。两个文件都被完全覆盖。

HANDOFF.md——组合参考文档:

头部:项目、更新时间戳、来自状态文件的分支/构建/测试

Items 表按 P0 → P2 排序,打开在阻塞之前

Log:仅最后 5 条条目

HANDOVER.md——静态 ASCII 依赖/流程图:

条目流用 [ ] 打开 / [!] 阻塞 / [x] 完成符号

depends_on 存在时内联显示

最近会话(最后 5 条 log 条目)

如果辅助脚本未找到或退出非零,回退到使用 Write 工具内联写入 .ctx/HANDOFF.md(模板来自上一步格式)。在这种情况下跳过 HANDOVER.md 并注明失败。

  1. 确保 .gitignore 覆盖 .ctx/

验证 .gitignore 包含:

.ctx/* !.ctx/HANDOFF..yaml .ctx/HANDOFF..state.yaml

如果不存在则添加或更新。此模式忽略所有 .ctx/ 内容,除了 HANDOFF 文件。

  1. 迁移预检

写入前,检查 HANDOFF 文件是否仍在仓库根目录。如果是,先迁移:

migrate-handoff <repo-root> <old-root-path>

然后暂存重命名并继续使用新的 .ctx/ 路径。

  1. 提交

git add <path-to-HANDOFF.yaml> .gitignore git commit -m "docs: update handoff"

仅暂存 .ctx/ 下的持久 HANDOFF 文件以及托管块所需的任何 .gitignore 更新。绝不暂存 .ctx/HANDOFF.*.state.yaml、.ctx/HANDOFF.md 或 .ctx/HANDOVER.md。

从零创建

从 git 上下文引导:

git log --oneline -10 git status

从最近提交填充 log。将 items 留空,或如果有明显的下一步则保留一个 P1。不要将已关闭的工作回填到 items,但确实保留持久的 log 历史。从实际构建/测试输出写入 .ctx/HANDOFF.<name>.<base>.state.yaml。

将新的 HANDOFF 文件放在 .ctx/HANDOFF.<name>.<base>.yaml,其中 <name> 是最近清单中的包/crate 名称,<base> 是仓库根目录名。使用 handoff-detect --name 获取正确的文件名。

旧版 HANDOFF.md

如果仓库根目录存在 HANDOFF.md 且不存在 HANDOFF.yaml:将其作为自由格式上下文读取,不要自动转换。注意可以创建 HANDOFF.yaml。