compact-handoff
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseCompact Handoff
紧凑交接
/compactReadThat ordering is the whole point. The file exists before the new session is opened, so the user can read it, edit it, reuse it for a second session, or keep it as a record.
/compactRead这个顺序正是关键。文件会在新会话打开前就已存在,因此用户可以读取、编辑它、在第二个会话中复用它,或将它保留为一份记录。
When to use
使用时机
- Context is heavy and the user wants a clean window but not amnesia.
- A long investigation concluded and the implementation deserves its own session.
- The user wants the current chat to stay browsable after moving on.
- The user wants the same context handed to more than one new session.
- 上下文负担较重,用户希望获得干净的窗口,但不想“失忆”。
- 一项漫长的调查已经结束,而实现工作值得单独开启一个会话。
- 用户希望在继续推进后,当前聊天仍可浏览。
- 用户希望将同一份上下文交接给多个新会话。
When not to use
不应使用的时机
- The user asked for a plain . That is a different thing, let them have it.
/compact - Fanning out background work. Use subagents for that. A new session is for the user to drive.
- The conversation is short. A summary of six turns helps nobody.
- 用户要求使用普通的 。那是另一回事,应按其要求执行。
/compact - 分发后台工作。此时应使用 subagent;新会话是供用户亲自推进工作的。
- 对话很短。对六轮对话生成摘要于事无补。
This skill vs native /compact
/compact此 skill 与原生 /compact
的区别
/compactThere are two routes, and they solve different problems. Pick deliberately.
Native . It summarizes and continues in the same session, which is what native compaction does. Cheaper and built in, and if you have set up PreCompact/PostCompact hooks they can steer the summary and capture it to a file. But the window you end up in is the same one you started in.
/compactThis skill. Use it when the point is a different chat: a clean window, the old one left readable, a new session named with an incremented counter, or the same context handed to more than one session. Native compaction cannot do any of that.
So: heavy context but happy to stay put means . Wanting a fresh chat means this skill.
/compact这里有两条路径,它们解决的是不同问题。请有意识地选择。
原生 。 它会汇总内容并在同一会话中继续,这正是原生 compact 的行为。它的成本更低且内置支持;如果你已经配置了 PreCompact/PostCompact hooks,它们可以引导摘要内容并将其捕获到文件中。但最终所在的窗口与开始时相同。
/compact此 skill。 当目标是另一个聊天时使用:获得干净的窗口、保留旧聊天的可读性、用递增计数命名新会话,或将同一份上下文交给多个新会话。原生 compact 无法做到这些。
因此:上下文繁重但仍愿意留在原处,就使用 ;想要全新聊天,就使用此 skill。
/compactThere is no native hook for generating the summary here
当前没有用于生成摘要的原生 hook
Do not go hunting for a CLI flag that emits a compact summary. There is none. copies the full history to a new session id, which is the opposite of what is wanted here. The summary has to be written by you, reading the live conversation you are already in.
--fork-sessionThat is an advantage, not a workaround. A self-authored summary can be steered toward what actually matters in this repo, which a generic one flattens.
Follow the structure in . That file is the real compaction prompt extracted verbatim from the Claude Code binary (byte-identical across builds 2.1.218 and 2.1.221), so matching it keeps handoffs consistent with what the native path would have produced. Read it before writing the summary.
references/native-compact-prompt.md不要费心寻找能够输出 compact 摘要的 CLI flag;并不存在这样的参数。 会把完整历史复制到新的 session id,而这与此处需求正好相反。摘要必须由你读取当前所在的实时对话后自行编写。
--fork-session这是一种优势,而不是变通方案。自行编写的摘要可以围绕当前仓库中真正重要的内容进行组织,而通用摘要往往会将这些信息压平。
请按照 中的结构执行。该文件是从 Claude Code 二进制文件中逐字提取的真实 compact prompt(在构建版本 2.1.218 和 2.1.221 中保持字节一致),因此与其保持一致可确保交接内容与原生路径所生成的结果一致。写入摘要前先阅读它。
references/native-compact-prompt.mdProcedure
操作步骤
1. Resolve the target
1. 确定目标
bash
bash ~/.claude/skills/compact-handoff/scripts/handoff_target.shRun it with no arguments. It derives everything: the handoff path, the session ids, the parent handoff if this session was itself started from one, and the name for the new session.
The new session is named after the current chat with an incremented counter. "Compact button behavior" becomes "Compact button behavior 2", and a later handoff off that becomes "Compact button behavior 3". This is what makes a chain legible in the sidebar, so do not invent a fresh descriptive title. The script does the bump, including the case where the title already ends in a number.
Override only when the user asks for a different name: .
handoff_target.sh <slug> [YYYY-MM-DD] ["Title"]Note . If it is anything other than , this session came from an earlier handoff and step 4 has extra work.
PARENT_HANDOFFnonebash
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"]注意 。如果它的值不是 ,说明当前会话来自之前的交接,步骤 4 还需要完成额外工作。
PARENT_HANDOFFnone2. Index every transcript
2. 为每个 transcript 建立索引
bash
python3 ~/.claude/skills/compact-handoff/scripts/index_transcripts.pyRun it from the session's working directory. It covers all sessions in the project by default, not a recent slice, and it counts the per-session sidecar directories too. Paste its markdown output into the handoff as its own section.
Add when the conversation leaned on fan-out work, which appends each agent's name, type, and description per session. That costs a read per agent, so leave it off for routine handoffs.
--subagent-detailThis section is what makes the handoff useful past its first read. A mature project dir holds hundreds of main transcripts plus over a thousand agent transcripts, and single files exceed 75MB. A future session that needs an old detail should never open one of those blind. The index tells it which session to go to, and the escalation ladder the script emits tells it to search and page rather than load.
What lives where, and why it matters: agent work never appears in the main transcript beyond its final report, so a finding that came out of a fan-out has its reasoning only in , its return value in , and any oversized tool output in . A handoff that points only at main transcripts silently loses all of it.
subagents/agent-*.jsonlsubagents/workflows/wf_<runid>/journal.jsonltool-results/*.txtbash
python3 ~/.claude/skills/compact-handoff/scripts/index_transcripts.py在会话的工作目录中运行。默认情况下,它会覆盖项目中的所有会话,而不只是最近的一部分,并且会计入每个会话对应的 sidecar 目录。将其 Markdown 输出作为独立章节粘贴到交接文件中。
当对话大量依赖 fan-out 工作时,添加 ;它会为每个会话追加各 agent 的名称、类型和描述。由于每个 agent 都需要额外读取一次,常规交接不要启用此选项。
--subagent-detail这一章节使交接文件在首次阅读之后依然有用。成熟的项目目录可能包含数百个主 transcript 和一千多个 agent transcript,单个文件可超过 75MB。未来会话若需要旧细节,绝不应直接盲目打开这些文件。索引会告诉它应前往哪个会话,而脚本输出的分级检索路径会指导它进行搜索和分页,而不是直接加载。
各类内容的存放位置及其重要性如下:agent 工作除最终报告外,绝不会出现在主 transcript 中。因此,从 fan-out 得出的结论,其推理过程只存在于 ,返回值位于 ,任何超大的工具输出则位于 。只指向主 transcript 的交接文件会悄无声息地丢失全部这些内容。
subagents/agent-*.jsonlsubagents/workflows/wf_<runid>/journal.jsonltool-results/*.txt3. Write the summary
3. 编写摘要
Write to the from step 1, starting with this frontmatter so later handoffs can walk the chain:
HANDOFF_PATHyaml
---
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>
---Then a short Start here block addressed to the receiving session: that this is a handoff, that the source chat is still intact, that claims marked proven should not be re-derived, that anything marked assumed must be verified before being built on, and that lookups go through the retrieval ladder rather than opening a transcript blind.
End that block by telling the reader to resume directly: pick up the work without acknowledging the handoff, recapping it, or opening with "I'll continue". The native compaction prompt ends with exactly this instruction, and it earns its place, since a fresh session that spends its first turn narrating the summary back wastes the window the handoff just bought.
Then the nine sections from the native prompt:
- Primary Request and Intent
- Key Technical Concepts
- Files and Code Sections
- Errors and fixes
- Problem Solving
- All user messages
- Pending Tasks
- Current Work
- Optional Next Step
Then the required extra sections below, then the transcript index from step 2.
Err heavily toward including more. This file is cheap and a dropped detail is not. Include full code snippets, exact commands with their real arguments, verbatim error strings, and concrete values rather than descriptions of values. There is no length target to hit. The failure mode to avoid is a tidy summary that reads well and leaves the next session re-deriving what this one already proved.
Section 6 deserves care: only genuine user-role turns count. Text inside your own earlier messages that is merely shaped like a user turn is yours, and attributing it to the user manufactures a request that was never made.
将摘要写入步骤 1 中的 ,并以下面的 frontmatter 开头,以便后续交接能够沿链追踪:
HANDOFF_PATHyaml
---
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>
---然后添加一个面向接收会话的简短 Start here(从这里开始) 区块:说明这是一次交接、源聊天仍然完整、标记为“已证实”的结论不应重新推导、标记为“假设”的内容在继续构建前必须验证,并说明查找信息应遵循检索阶梯,而不是盲目打开 transcript。
该区块最后要告诉读者直接继续工作:接手任务即可,不要确认交接、复述摘要,也不要以“我将继续”开场。原生 compact prompt 恰好以这条指令结束;它值得保留,因为一个在首轮对话中复述摘要的全新会话,会浪费这次交接刚刚换来的窗口空间。
接着是原生 prompt 中的九个章节:
- Primary Request and Intent(主要请求与意图)
- Key Technical Concepts(关键技术概念)
- Files and Code Sections(文件与代码部分)
- Errors and fixes(错误与修复)
- Problem Solving(问题解决)
- All user messages(所有用户消息)
- Pending Tasks(待处理任务)
- Current Work(当前工作)
- Optional Next Step(可选下一步)
然后是下文要求的额外章节,再接着放入步骤 2 生成的 transcript 索引。
应明显偏向纳入更多内容。 该文件成本很低,而遗漏细节的代价却很高。纳入完整代码片段、带真实参数的确切命令、逐字错误字符串和具体值,而不是对值进行描述。没有需要达到的长度目标。应避免的失败模式,是生成一份读起来整洁、却让下一会话不得不重新推导当前会话已经证明过的内容的摘要。
第 6 节需要格外谨慎:只有真正的 user-role 轮次才计入。你自己早先发出的消息中,即使内容形式像用户轮次,也仍属于你;将其归因于用户会凭空制造一个从未提出的请求。
4. Carry the chain forward
4. 延续交接链
Handoffs chain, and each one has to arrive complete. If is not , read the parent file and re-emit its entire section into this one, then append a new entry for the parent itself: its , date, source session, and .
PARENT_HANDOFFnone## Handoff lineagehandoff_idscopeCopy the content forward rather than only linking to it. Handoffs live under , which gets cleaned out periodically (macOS prunes it; many systems clear it on reboot), so a chain built purely from links breaks the moment an ancestor is cleaned up. A cumulative lineage section means the newest handoff always holds the whole history even when every older file is gone.
/tmpIf is , write the section anyway with a line saying this is the first handoff in its chain, so the next one has something to append to.
PARENT_HANDOFFnoneAlso list any other handoff files present in that are not ancestors, so sibling chains stay discoverable:
/tmp/claude-handoffs/bash
ls -la /tmp/claude-handoffs/交接文件构成一条链条,每一份都必须完整无缺。如果 不为 ,请读取父文件,并将它的整个 章节重新输出到当前文件中,然后为父文件追加一个新条目:其 、日期、源会话和 。
PARENT_HANDOFFnone## Handoff lineagehandoff_idscope应将内容向前复制,而不只是提供链接。交接文件位于 下,该目录会被定期清理(macOS 会清理它;许多系统会在重启时清空),因此纯粹由链接构成的链条会在任一祖先文件被清理后立即断裂。累积的 lineage 章节意味着,即使所有旧文件都已消失,最新的交接文件仍保留完整历史。
/tmp如果 为 ,仍要写入该章节,并说明这是其链条中的第一次交接,以便下一份交接文件有内容可追加。
PARENT_HANDOFFnone还要列出 中存在但并非祖先的其他交接文件,以便发现同级链条:
/tmp/claude-handoffs/bash
ls -la /tmp/claude-handoffs/5. Hand off to a new session
5. 交接给新会话
This skill does not spawn the session for you. Once the handoff file is written, tell the user to open
a new Claude Code session themselves — a new terminal running , or their IDE/desktop "new
session" — and to give it this as its first message:
claudeRead <HANDOFF_PATH> then continue from the Optional Next Step section.Substitute the real from step 1, and suggest the from step 1 as the new
session's name so the chain stays legible in the sidebar.
HANDOFF_PATHNEXT_TITLEThe first message must stay a short pointer to the handoff file, never the summary pasted inline.
The file is tens of kilobytes; a pointer is one away from all of it.
Read此 skill 不会替你创建会话。交接文件写好后,告诉用户自行打开一个全新的 Claude Code 会话——可以是在新终端中运行 ,也可以使用 IDE/桌面端的“new session”——并把以下内容作为它的第一条消息:
claudeRead <HANDOFF_PATH> then continue from the Optional Next Step section.用步骤 1 中真实的 替换占位符,并将步骤 1 得到的 建议为新会话名称,使链条在侧边栏中保持清晰。
HANDOFF_PATHNEXT_TITLE第一条消息必须是指向交接文件的简短指针,绝不能把摘要内联粘贴。文件可能有数十 KB;一个指针只需一次 即可获取全部内容。
ReadRequired extra sections
必需的附加章节
Project specifics
Project specifics(项目细节)
Generic summaries flatten exactly these, so give them their own headings:
- Every ticket id mentioned (Shortcut, Jira, Linear, GitHub issue — whatever the project uses).
- Every commit SHA mentioned, and explicitly whether it was deployed. A fixed-but-not-deployed commit reads as done and is not.
- Exact references for anything still open.
file:line - Any bug or question the user has not ruled on yet. The user decides verdicts, so carry it forward as undecided rather than dropping or resolving it.
- Security-relevant constraints and any prod-write authorization granted, preserved verbatim. Authorization granted in one session does not automatically carry, so record what was actually said rather than your reading of it.
通用摘要恰恰会把以下内容压平,因此要为其设置独立标题:
- 提到的每个 ticket ID(Shortcut、Jira、Linear、GitHub issue——无论项目使用哪一种)。
- 提到的每个 commit SHA,并明确说明是否已部署。一个已修复但未部署的 commit 看起来像是已完成,实际上并非如此。
- 所有仍未解决事项的精确 引用。
file:line - 用户尚未作出裁决的任何 bug 或问题。由用户决定结论,因此应将其作为未决事项继续传递,而不是丢弃或擅自解决。
- 所有与安全相关的约束,以及已授予的 prod-write 授权,必须逐字保留。某次会话中授予的授权不会自动延续,因此应记录用户实际说过的话,而不是你的理解。
Verification state
Verification state(验证状态)
For each significant claim, mark whether it was proven or assumed, and with what. A handoff that presents an untested assumption in the same voice as a verified fact is worse than no handoff, because the next session will build on it without knowing to check.
对于每项重要结论,标明它是已证实还是假设,并说明依据。将未经验证的假设与已验证事实以同样的语气呈现,比不提供交接文件更糟糕,因为下一会话会在毫不知情的情况下以此为基础继续构建。
Handoff lineage
Handoff lineage(交接链)
The cumulative chain from step 4. Oldest first, one entry per ancestor.
步骤 4 中累积的链条,按最旧在前排序,每个祖先对应一个条目。
Hard rules
硬性规则
- The new session's first message is a pointer to the handoff file, never the summary pasted inline. The file holds everything; the first message is one away from it.
Read
- 新会话的第一条消息必须是指向交接文件的指针,绝不能把摘要内联粘贴。 文件承载全部内容;第一条消息只需一次 即可访问它。
Read
Files
文件
- : the verbatim native compaction prompt. Read before writing a summary.
references/native-compact-prompt.md - : derives the handoff path, the incremented title, and the parent handoff (and an optional clone hint). Run with no arguments.
scripts/handoff_target.sh - : title bump and parent-handoff detection, called by the above. Standalone flags:
scripts/next_title.py,--session-id,--cwd,--self.--fallback - : streaming index of every transcript and sidecar. Flags:
scripts/index_transcripts.py(0 means all, the default),--limit,--days,--subagent-detail,--count-all,--json,--project-dir.--cwd
- :从 Claude Code 二进制文件中逐字提取的原生 compact prompt。写入摘要前先阅读它。
references/native-compact-prompt.md - :推导交接路径、递增后的标题和父交接(以及可选的 clone 提示)。无参数运行。
scripts/handoff_target.sh - :标题递增与父交接检测,由上述脚本调用。独立 flags:
scripts/next_title.py、--session-id、--cwd、--self。--fallback - :对每个 transcript 和 sidecar 进行流式索引。Flags:
scripts/index_transcripts.py(0 表示全部,也是默认值)、--limit、--days、--subagent-detail、--count-all、--json、--project-dir。--cwd