mcpField
C
compact-handoff

compact-handoff

github.com/marks97Agent 工作流0230 次安装4 周前更新
代码仓库

关于 compact-handoff

用于把当前会话整理成文件并交给新会话继续工作的技能,面向需要保留旧聊天并开启干净上下文的 Claude Code 用户。它会整理摘要、会话索引和交接链,而不修改当前聊天。

主要功能

  1. 01将摘要写入交接文件
  2. 02索引项目中的会话记录
  3. 03保留交接链与项目细节
  4. 04标注已验证和待核实信息
  5. 05生成新会话的交接指引

适用场景

  1. 01在长时间调查后开启实现会话
  2. 02保留当前聊天并转入新会话
  3. 03将同一上下文交给多个新会话

安装

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

$npx skills add https://github.com/marks97/compact-handoff --skill compact-handoff

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

包含的文件

除 SKILL.md 外,安装时一起下载的参考资料和脚本。

references/
native-compact-prompt.md
scripts/
handoff_target.sh
index_transcripts.py
next_title.py

详细介绍

紧凑交接

/compact 会就地修改当前会话。应用摘要之前,你无法看到它;旧细节也无法再从当前窗口中访问。此技能则恰好相反:先将一份详尽的摘要写入文件,保持当前聊天原样不动,然后在新会话中通过一次 Read 载入摘要。

这个顺序正是关键所在。新会话打开之前,文件就已存在,因此用户可以阅读、编辑、在另一个会话中复用,或将其留作记录。

适用场景

  • 上下文很长,用户想要一个干净的窗口,但不想失去记忆。
  • 一项长期调查已经结束,接下来应在独立会话中进行实现。
  • 用户希望继续浏览当前聊天,同时开始后续工作。
  • 用户希望将相同的上下文交接给多个新会话。

不适用场景

  • 用户要求执行普通的 /compact。这不是一回事,按用户的要求执行即可。
  • 分派后台工作。此时应使用子 Agent。新会话是留给用户主导的。
  • 对话很短。总结六轮对话没有意义。

此技能与原生 /compact 的区别

有两种路径,解决的是不同问题。请有意识地选择。

原生 /compact。 它会在同一会话中总结并继续,这正是原生压缩的作用。成本更低且内置;如果你已设置 PreCompact/PostCompact 钩子,它们可以引导摘要并将其保存到文件。但最终进入的仍是你开始时所在的窗口。

此技能。 当你需要的是另一个聊天时使用:一个干净的窗口、旧聊天仍可阅读、以递增计数器命名的新会话,或将相同的上下文交接给多个会话。原生压缩无法做到这些。

因此:上下文很长但愿意留在当前会话中,就用 /compact。想要一个新的聊天,就用此技能。

此处没有用于生成摘要的原生钩子

不要费力寻找能输出紧凑摘要的 CLI 标志。没有这样的标志。--fork-session 会将完整历史记录复制到新的会话 ID,这与此处的需求恰好相反。摘要必须由你读取当前所在会话的实时对话后自行撰写。

这不是权宜之计,而是优势。自行撰写的摘要可以聚焦于此仓库中真正重要的内容,而通用摘要会把这些细节一概压平。

遵循 references/native-compact-prompt.md 中的结构。该文件是从 Claude Code 二进制文件中逐字提取的真实压缩提示词(在 2.1.218 和 2.1.221 版本构建中逐字节相同),因此按照它来写,可以让交接内容与原生路径生成的内容保持一致。撰写摘要前请先阅读该文件。

流程

1. 确定目标
bash ~/.claude/skills/compact-handoff/scripts/handoff_target.sh

不带参数运行。它会推导出所有信息:交接文件路径、会话 ID、如果当前会话本身由先前的交接启动时所对应的父级交接,以及新会话的名称。

新会话以当前聊天的名称命名,并将计数器加一。“Compact button behavior”会变成“Compact button behavior 2”,之后基于该会话继续交接,则会变成“Compact button behavior 3”。这样可以让侧边栏中的会话链一目了然,因此不要另起一个描述性标题。该脚本会递增计数器,包括标题本身已以数字结尾的情况。

仅当用户要求使用不同名称时才覆盖:handoff_target.sh <slug> [YYYY-MM-DD] ["Title"]。

留意 PARENT_HANDOFF。如果其值不是 none,则此会话来自先前的交接,第 4 步还有额外工作。

2. 为每份对话记录建立索引
python3 ~/.claude/skills/compact-handoff/scripts/index_transcripts.py

在会话的工作目录中运行。默认情况下,它会涵盖项目中的所有会话,而非仅涵盖最近一部分;它也会统计每个会话的附属目录。将它的 Markdown 输出粘贴到交接文档中,作为单独的章节。

如果对话大量依赖扇出式工作,可添加 --subagent-detail,这样会在每个会话下附加各个 Agent 的名称、类型和描述。每个 Agent 都需要读取一次,因此常规交接时请不要启用。

这一章节能让交接文档在首次阅读后依然有用。成熟项目目录中可能有数百份主对话记录,以及上千份 Agent 对话记录;单个文件甚至超过 75MB。后续会话若要查找旧细节,绝不能盲目打开这些文件。索引会指出要查阅哪个会话,而脚本输出的逐级检索指南则会告诉它如何搜索和分页,而不是直接加载文件。

内容分别存在哪里,以及为何重要:Agent 的工作除了最终报告外,绝不会出现在主对话记录中。因此,扇出任务中得出的发现,其推理过程只存在于 subagents/agent-*.jsonl,返回值存在于 subagents/workflows/wf_<runid>/journal.jsonl,超大的工具输出则存在于 tool-results/*.txt。交接文档若只指向主对话记录,就会悄无声息地丢失所有这些内容。

3. 撰写摘要

写入第 1 步中的 HANDOFF_PATH,并以以下前置元数据开头,以便后续交接能够沿着链条追溯:

---
handoff_id: <date>-<slug>
created: <date>
source_session: <SESSION_ID>
parent_handoff: <PARENT_HANDOFF, or none>
clone: <CLONE>
cwd: <CWD>
scope: <one line on what this handoff covers>
---

接着写一段简短的从这里开始说明,面向接收会话:说明这是一份交接文档,源聊天记录仍然完整,标记为已证实的说法不应重新推导,标记为假设的内容必须先验证再据此开展工作,并且查找内容时应遵循检索阶梯,而不是盲目打开对话记录。

在这段说明末尾,告诉读者直接继续工作:接手当前工作,不必确认已收到交接、复述交接内容,也不要以“我会继续”开头。原生压缩提示词的结尾正是这条指示,而且它确实有必要:新会话若在第一轮就把摘要复述一遍,只会浪费交接文档刚刚节省下来的上下文窗口。

然后添加原生提示词中的九个章节:

  1. 主要请求与意图
  2. 关键技术概念
  3. 文件与代码段
  4. 错误与修复
  5. 问题解决
  6. 所有用户消息
  7. 待处理任务
  8. 当前工作
  9. 可选的下一步

然后添加下方要求的额外章节,再添加第 2 步中的对话记录索引。

宁可多写,绝不要少写。 这个文件代价很低,遗漏细节的代价却不低。请包含完整代码片段、带实际参数的准确命令、逐字记录的错误信息,以及具体值,而不是对值的描述。没有字数目标。需要避免的失败模式,是写出一份整洁好读的摘要,却让下一会话不得不重新推导本会话已经证实的内容。

第 6 节需要特别谨慎:只有真正由用户角色发出的消息才算。你先前消息中的文本,即便只是形式上像用户发言,也是你自己的内容;将其归到用户名下,就会凭空捏造一个用户从未提出过的请求。

4. 延续链条

交接会形成链条,每次交接都必须完整传递。如果 PARENT_HANDOFF 不是 none,请读取父级文件,并将其中完整的 ## Handoff lineage 部分重新写入当前文件,然后追加一条父级记录:其 handoff_id、日期、源会话和 scope。

请复制内容,而不只是添加链接。交接文件位于 /tmp 下,会定期清理(macOS 会清理这些文件;许多系统会在重启时清空它们),因此,纯链接构成的链条会在某个祖先文件被清理时立即断裂。累积式的 lineage 部分可以确保最新的交接文件始终包含完整历史,即使所有较旧文件都已消失。

如果 PARENT_HANDOFF 是 none,也要写入该部分,并注明这是此链条中的首次交接,以便下一次交接有内容可追加。

还要列出 /tmp/claude-handoffs/ 中所有不属于祖先链的其他交接文件,以便发现同级链条:

ls -la /tmp/claude-handoffs/
5. 移交给新会话

此技能不会替你启动新会话。写入交接文件后,告知用户由他们自行打开一个新的 Claude Code 会话——可以在新终端中运行 claude,也可以在 IDE/桌面应用中选择“新建会话”——并将以下内容作为该会话的第一条消息:

Read <HANDOFF_PATH> then continue from the Optional Next Step section.

将第 1 步中的真实 HANDOFF_PATH 替换进去,并建议将第 1 步中的 NEXT_TITLE 用作新会话的名称,以便在侧边栏中清晰查看链条。

第一条消息必须简短,作为交接文件的指针,绝不能直接粘贴摘要。该文件有数万字节;只需通过一个 Read 操作即可读取全部内容。

必需的额外部分

项目详情

通用摘要会抹平以下重要内容,因此请为它们分别设置标题:

  • 提及的所有工单 ID(Shortcut、Jira、Linear、GitHub issue——无论项目使用什么)。
  • 提及的所有提交 SHA,并明确说明是否已部署。已修复但尚未部署的提交看起来像是已经完成,实际却并非如此。
  • 所有仍待处理事项的精确 file:line 引用。
  • 用户尚未排除的任何错误或问题。由用户决定结论,因此应将其作为未决事项继续传递,而不是省略或自行定论。
  • 与安全相关的约束,以及任何已授予的生产环境写入授权,都要原样保留。某个会话中授予的授权不会自动延续,因此要记录实际说过的话,而不是你对其含义的解读。
验证状态

对于每项重要说法,标明它是已证实还是假设,并说明依据。交接若用与已验证事实相同的口吻陈述未经测试的假设,比不写交接更糟糕,因为下一会话会在不知道需要核验的情况下继续推进。

Handoff lineage

按照第 4 步累积链条中的内容,从最早的祖先开始,每位祖先列一条记录。

硬性规则

  • 新会话的第一条消息必须是指向交接文件的指针,绝不能直接粘贴摘要。 文件包含全部内容;第一条消息只需一个 Read 操作即可读取。

文件

  • references/native-compact-prompt.md:原样的原生压缩提示词。编写摘要前请先阅读。
  • scripts/handoff_target.sh:推导交接路径、递增后的标题和父级交接信息(以及可选的克隆提示)。不带参数运行。
  • scripts/next_title.py:标题递增及父级交接检测,由上述脚本调用。独立运行时的标志:--session-id、--cwd、--self、--fallback。
  • scripts/index_transcripts.py:对所有 transcript 和 sidecar 进行流式索引。标志:--limit(0 表示全部,且为默认值)、--days、--subagent-detail、--count-all、--json、--project-dir、--cwd。

评论

支持 Markdown