smart-precompact

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

smart-precompact

smart-precompact

The task: pull out of the conversation what is worth surviving, and hand over prompts that let the session continue after the compact without feeling like you are talking to someone new.
The success test: after the compact, the session does not repeat a mistake that was already made, does not ask a question the user already answered, and does not suggest an approach that was already rejected.
Speed contract: the run is measured in seconds. No file search, no folder scan, no
find
. The skill runs when the context is already full, and every unnecessary call brings the automatic compact closer.
Language: these instructions are in English, but everything the user sees follows the language of the user's messages: the receipt line, block 1, block 2 (translate its labels naturally, for example "Building:" and "Failed, don't retry:"), and block 3. Three things never change: the
/compact
command itself, exact strings copied from the session (errors, paths, commands), and the handoff file's first line
# Handoff . <root> . <date and time>
, which the hook uses to recognize its own files.

任务:从对话中提取值得保留的内容,并交接提示词,让会话在压缩后继续时,不会让人觉得是在与一个不了解前情的人交谈。
成功标准:压缩后,会话不会重复已经犯过的错误,不会再次询问用户已经回答过的问题,也不会提出用户已经否决的方案。
速度约定:整个运行过程以秒计。不得搜索文件、扫描文件夹或执行
find
。该 skill 运行时上下文已经接近占满,每一次不必要的调用都会让自动压缩更早触发。
语言:这些说明使用英文,但用户看到的所有内容都应遵循用户消息的语言:回执行、内容块 1、内容块 2(自然地翻译其中的标签,例如“构建中:”和“失败,不要重试:”),以及内容块 3。 有三项内容始终不变:
/compact
命令本身、从会话中原样复制的字符串(错误、路径、命令),以及交接文件的第一行
# Handoff . <root> . <date and time>
,hook 使用该行识别自己创建的文件。

Run modes

运行模式

ArgumentWhat happens
(empty)Default. Reads, filters, prints the blocks. Zero writes to disk
handoff
Also saves the resume prompt to one file outside the project, so a new session can continue from it
save
Also appends items to documentation files that already exist in the project
save notes
Like
save
, and also writes to the personal notes folder. Only on explicit request, and only if the path is set in
config.md
Modes combine, for example
handoff save
. The default touches nothing.
Request in words: "prep me for compact and save" or "so I can continue tomorrow" =
handoff
. "and update the docs" =
save
. "also to my notes" or "also to Obsidian" =
save notes
. The same request in any language means the same mode. When in doubt, the default.
参数发生什么
(空)默认。 读取、筛选并打印内容块。完全不写入磁盘
handoff
还会将续接提示词保存到项目之外的单个文件中,以便新会话从该文件继续
save
还会将条目追加到项目中已经存在的文档文件里
save notes
与
save
相同,还会写入个人笔记文件夹。仅在明确请求时执行,并且只有
config.md
中已设置路径才可执行
模式可以组合,例如
handoff save
。默认模式不会触及任何内容。
用自然语言提出请求:“帮我准备压缩并保存”或“这样我明天可以继续”表示
handoff
;“并更新文档”表示
save
;“也写到我的笔记里”或“也写到 Obsidian”表示
save notes
。任何语言表达的相同请求都对应相同模式。有疑问时使用默认模式。

Automatic trigger (hook, optional)

自动触发(hook,可选)

scripts/compact_hook.py
is installed with
scripts/install_hook.py
(see
README.md
). It does two things:
  1. Before a compact: adds a note to the conversation when the context passes the first threshold (60%), and again at the second (80%). When the note appears:
    • Answer what the user asked first. Do not stop their work for the skill.
    • At the end of that same reply, run the skill in
      handoff
      mode, with the path from the note.
    • One line to the user, in the language of their message: the context passed X%, and the /compact line is ready. At the second threshold the wording is sharper: now is the time to compact (Smart compact in the band above the prompt, when it shows, or paste the line), before the automatic compact runs on its own.
    • The user already asked for the skill in that same message? Run once, and add
      handoff
      .
  2. After a compact: puts the session's handoff file back into the conversation by itself. So when the hook is installed, the user only has to press Smart compact in the band, or paste the /compact line.

scripts/compact_hook.py
随
scripts/install_hook.py
一同安装(参见
README.md
)。 它会执行两件事:
  1. 压缩前: 当上下文达到第一个阈值(60%)时向对话添加一条说明,达到第二个阈值(80%)时再次添加。出现说明时:
    • 先回答用户提出的问题。 不要为了运行该 skill 而中断用户的工作。
    • 在同一条回复的末尾,以
      handoff
      模式运行该 skill,并使用说明中给出的路径。
    • 用用户消息所用的语言向用户提供一行信息:上下文已越过 X%,并且
      /compact
      命令已经准备好。达到第二个阈值时,措辞应更明确:现在就是压缩的时候(在提示框上方显示 Smart compact 区域时点击它,或粘贴该命令),以便在自动压缩自行运行之前完成操作。
    • 用户是否已经在同一条消息中请求了该 skill?运行一次,并添加
      handoff
      。
  2. 压缩后: 自动将会话的交接文件放回对话中。因此安装 hook 后,用户只需在相应区域点击 Smart compact,或粘贴
    /compact
    命令。

Step 1: Context (one command)

第 1 步:上下文(一个命令)

bash
date "+%Y-%m-%d %H:%M"; echo "root: $(git rev-parse --show-toplevel 2>/dev/null || pwd)"; echo "session: ${CLAUDE_CODE_SESSION_ID:-none}"; git status --short 2>/dev/null | head -10; grep -qs compact_hook.py ~/.claude/settings.json && echo "restore-hook: on"
That is all. No
ls
and no scan.
root
is the project root: every project path (
docs/
,
CLAUDE.md
) is read from it, even if the conversation moved into a subfolder. Branch and commit do not go into the prompt: Claude Code loads fresh git state by itself, after a compact and in every new session.
Was the conversation already compacted once? (Part of it shows up for you as a summary.) Read the session's handoff file if it exists (the path is in step 4b, so this is a read and not a search). It is the record of what came before the compaction. No file? Say in the receipt line that part of the conversation is available to you only as a summary, and do not make things up about it.

bash
date "+%Y-%m-%d %H:%M"; echo "root: $(git rev-parse --show-toplevel 2>/dev/null || pwd)"; echo "session: ${CLAUDE_CODE_SESSION_ID:-none}"; git status --short 2>/dev/null | head -10; grep -qs compact_hook.py ~/.claude/settings.json && echo "restore-hook: on"
仅此而已。不要执行
ls
,也不要进行扫描。
root
是项目根目录:所有项目路径(
docs/
、
CLAUDE.md
)都从该目录读取,即使对话已进入子文件夹。分支和 commit 不写入提示词:每次压缩之后以及每个新会话中,Claude Code 都会自行加载最新的 git 状态。
对话此前是否已经压缩过一次?(其中一部分会作为摘要呈现给你。)如果会话的交接文件存在,则读取该文件(路径见第 4b 步,因此这是读取而不是搜索)。该文件记录了压缩前发生的事情。如果没有文件,请在回执行中说明对话的某一部分仅以摘要形式对你可见,不要凭空补全。

Step 2: Triage

第 2 步:分类筛选

Go through the conversation. For each item ask: "If this disappears, what breaks in the next session?"
Five categories, in order of importance:
  1. Dead ends. What we tried and failed, and why. The most expensive category. Without it the next session tries the same approach again.
  2. Decisions. We chose X over Y, and there is a reason. Without the reason it is not a decision.
  3. User corrections. "No, like this", "always do". Working rules, in the user's own words.
  4. Working state. Which files we touched, what is half done, what is untested.
  5. Open items. What is left, in order.
Exact wording. When an item depends on a string (a path, an error message, a field name, a command), copy it word for word. A summary of an error message is already a different error message.
Never secrets. An API key, token, password, connection string or card number is replaced with
[REDACTED: what it is]
, even inside an exact string. The blocks get saved to files and pasted into conversations, and a secret that gets into them has already left.
逐项检查对话内容。每一项都要问:“如果它消失了,下一个会话中什么会出问题?”
按重要性分为五类:
  1. 失败路径。 尝试过但失败的内容,以及失败原因。成本最高的一类。 如果不保留,下一个会话会再次尝试相同方案。
  2. 决策。 选择了 X 而没有选择 Y,以及这样选择的原因。没有原因的描述不能算作决策。
  3. 用户纠正。 “不,像这样”“始终这样做”等内容。这些是工作规则,应使用用户自己的原话。
  4. 工作状态。 修改过哪些文件、哪些工作完成了一半、哪些内容尚未测试。
  5. 待办事项。 剩余工作及其优先顺序。
准确措辞。 如果某一项依赖特定字符串(路径、错误消息、字段名、命令),必须逐字复制。对错误消息进行概括后得到的已经是另一个错误消息。
绝不包含秘密。 API key、token、密码、连接字符串或卡号必须替换为
[REDACTED: what it is]
,即使它位于逐字复制的字符串内部也是如此。内容块会被保存到文件并粘贴进对话,秘密一旦进入其中就已经暴露。

The omission test

遗漏测试

Drop every item that:
  • git, the code or CLAUDE.md already say (CLAUDE.md is reloaded after every compact)
  • is true only for this moment in the conversation ("show me the file", intermediate wording)
  • was replaced by a later conclusion
An average item is worth one line, not a paragraph. If more than 8 items came out, you did not filter.

删除以下所有条目:
  • git、代码或
    CLAUDE.md
    已经说明的内容(
    CLAUDE.md
    会在每次压缩后重新加载)
  • 只在当前对话时刻有意义的内容(“把文件显示给我”、临时措辞)
  • 已被后续结论取代的内容
普通条目应控制在一行以内,而不是一段话。如果整理出了超过 8 项,说明过滤得不够充分。

Step 3: Writing the blocks

第 3 步:编写内容块

Read
reference/prompt-templates.md
, and write both blocks before any write to disk. The handoff file is a copy of block 2, so block 2 must be final before it is saved.
The split:
  • Block 2 (the resume prompt) stands on its own. It is also the file a new session will read, and a new session has no summary. So it carries everything: dead ends with the reason, decisions with the reason, rules, state, pointers to files, and the next step.
  • Block 1 (the /compact line) protects the reasoning inside the summary. It tells the summarizer what to keep and what to compress. Never state.
  • The only overlap allowed: dead ends and user corrections, briefly. They are the most expensive to lose, and a duplicated line is cheaper than a session that repeats the same mistake. And from the other side: an area that holds a dead end never goes into "can compress".
Length: a compact line up to 60 words. A resume prompt up to 200 words, and up to 3 steps in "Next up".

阅读
reference/prompt-templates.md
,并在写入磁盘前编写两个内容块。交接文件是内容块 2 的副本,因此保存前内容块 2 必须已经定稿。
划分方式:
  • 内容块 2(续接提示词)必须能够独立使用。 它同时也是新会话会读取的文件,而新会话没有摘要。因此它需要承载全部信息:带有原因的失败路径、带有原因的决策、规则、状态、文件指针和下一步。
  • 内容块 1(
    /compact
    命令)用于保护摘要中的推理过程。
    它告诉摘要器哪些内容需要保留、哪些内容可以压缩。绝不描述当前状态。
  • **唯一允许的重复:**简要重复失败路径和用户纠正。这些内容一旦丢失代价最高,而多写一行远比让会话重复犯错更便宜。反过来,包含失败路径的领域绝不能被列入“可以压缩”的内容。
长度:压缩命令最多 60 个词。续接提示词最多 200 个词,“下一步”中最多包含 3 个步骤。

Step 4: Writing (only if requested)

第 4 步:写入(仅在明确请求时)

Without
save
,
save notes
or
handoff
, skip this step entirely.
如果未请求
save
、
save notes
或
handoff
,则完全跳过此步骤。

4a. save

4a. save

Write only to files that already exist, relative to
root
. Never create a file or folder in the project. No target at all? Say so in the receipt line, and the items stay in block 2.
WhatWhereCap per run
Decisions and dead ends
docs/DECISIONS.md
2
Open items, and
[x]
on what was completed
docs/TASKS.md
5
An explicit working rule
CLAUDE.md
in the project root
1, and almost always 0
Formats, edge cases and contradictions:
reference/routing-table.md
.
The bar for CLAUDE.md. The file is loaded into every session, forever, and a redundant line there costs tokens in every future conversation. A line goes in only if all three hold: (1) the user said it explicitly ("always", "never", "no, like this"), and a rule is never inferred; (2) it is not already covered there in other words (read before you write); (3) deleting it would change future behavior. When in doubt, do not write, and note in the receipt that there was a candidate and why it was rejected.
Append-only. No rewriting, no deleting, no "cleaning up". Only two exceptions: marking
[x]
on a completed task, and correcting a line you wrote in this same run when the user corrected its routing right away. Read before you write, and skip an item that is already there.
只能写入相对于
root
已经存在的文件。绝不在项目中创建文件或文件夹。如果完全没有目标,请在回执行中说明,相关条目仍保留在内容块 2 中。
内容写入位置每次运行上限
决策和失败路径
docs/DECISIONS.md
2
待办事项,以及在已完成事项上标记
[x]
docs/TASKS.md
5
用户明确提出的工作规则项目根目录中的
CLAUDE.md
1,而且通常应为 0
格式、边界情况及矛盾处理参见
reference/routing-table.md
。
写入
CLAUDE.md
的标准。
该文件会在每个会话中加载,并永久保留;其中一行冗余内容会在未来的每次对话中消耗 token。只有同时满足以下三项条件时才能写入一行:(1) 用户明确说过该规则(“始终”“绝不”“不,像这样”),绝不推断规则;(2) 换一种说法后该文件尚未涵盖此规则(写入前先阅读);(3) 删除这一行会改变未来的行为。有疑问时不要写入,并在回执中说明存在一个候选规则以及拒绝写入的原因。
仅追加。 不重写、不删除,也不“清理”。只有两种例外:标记已完成任务的
[x]
,以及用户立即纠正了本次运行的路由方式时,修正本次运行中刚写入的一行。写入前先阅读,并跳过已经存在的内容。

4b. handoff

4b. handoff

The path: does the hook note give a path? Use it. Otherwise
~/.claude/handoffs/<first 8 characters of session>.md
. If session is
none
:
~/.claude/handoffs/<name of the root folder>.md
.
The content: first line
# Handoff . <root> . <date and time from step 1>
, an empty line, then block 2 as written in step 3, and as the very last line block 1 in a hidden comment:
<!-- compact: <block 1 without the leading /compact, on one line> -->
. The Smart PreCompact mod reads that line to run exactly this compact in one click; the hook strips it before it puts the file back into the conversation. One file per session, overwritten on every run, no archive: working state goes stale, and an old version of it misleads. The hook deletes a file nobody touched for 14 days, and identifies it by the first line: do not change the header, or the file will never be deleted. This is the only file the skill creates outside the project. Folder missing?
mkdir -p ~/.claude/handoffs
.
路径: hook 说明中给出了路径吗?如果有,直接使用。否则使用
~/.claude/handoffs/<first 8 characters of session>.md
。如果 session 为
none
,则使用
~/.claude/handoffs/<name of the root folder>.md
。
**内容:**第一行为
# Handoff . <root> . <date and time from step 1>
,然后是一个空行,接着是第 3 步定稿的内容块 2。最后一行以隐藏注释形式保存内容块 1:
<!-- compact: <block 1 without the leading /compact, on one line> -->
。Smart PreCompact 模组读取这一行,以便一键运行完全相同的压缩流程;hook 在把文件放回对话前会移除该行。**每个会话只有一个文件,每次运行都会覆盖,不设归档:**工作状态会过时,旧版本会产生误导。hook 会删除 14 天内无人修改的文件,并通过第一行识别这些文件:不要更改标题,否则文件将永远不会被删除。这是该 skill 在项目之外唯一会创建的文件。如果文件夹不存在,执行
mkdir -p ~/.claude/handoffs
。

4c. save notes

4c. save notes

The path and folder names come from
config.md
in the skill folder. Do not search. No path, or it does not exist on disk? One line in the receipt, and skip. Formats:
reference/routing-table.md
. In the notes folder you may create today's log if it does not exist yet, and a new file for each decision (
<decisions>/YYYY-MM-DD <short title>.md
).

路径和文件夹名称来自 skill 文件夹中的
config.md
。不要搜索。 如果没有路径,或该路径在磁盘上不存在,请在回执中用一行说明并跳过。格式参见
reference/routing-table.md
。在笔记文件夹中,如果今天的日志尚不存在,可以创建它;每项决策还可以创建一个新文件(
<decisions>/YYYY-MM-DD <short title>.md
)。

Step 5: The output

第 5 步:输出

One receipt line, in the language of the conversation (even when the last message is only a command): how many items, what was written and where, what was dropped and why, contradictions found, and whether the conversation was compacted before. When run from the hook, this line also includes the percentage, and there is no extra line.
Then the blocks, of type
text
and not
bash
, with no text between them.
(In some interfaces a bash block gets a Run button, and clicking it runs the text in the terminal.)
ModeWhat is printed
Without
handoff
Block 1, block 2
handoff
, without
restore-hook: on
Block 1 (ends with the file path), block 2, block 3
handoff
and
restore-hook: on
Block 1 (ends with the file path), block 3. The receipt line says the resume prompt was saved and will come back into the conversation by itself after the compact
Block 3 is one sentence for a new session:
Read <path> and continue from there.
Is the next task unrelated to what we did? Add a line: better to
/clear
and start a clean session with block 2 or 3. A clean session costs less than a compact, and does not carry a summary it does not need.
输出一行回执,使用对话所用的语言(即使最后一条消息只有一条命令):包含条目数量、写入内容及其位置、删除内容及其原因、发现的矛盾,以及对话此前是否已经压缩过。从 hook 运行时,该行还要包含百分比,并且不增加其他行。
随后输出内容块,类型必须是
text
而不是
bash
,并且内容块之间不要插入任何文字。(某些界面会将 bash 块显示为 Run 按钮,点击后会在终端中执行其中的文本。)
模式输出内容
不使用
handoff
内容块 1、内容块 2
使用
handoff
,但没有
restore-hook: on
内容块 1(末尾带文件路径)、内容块 2、内容块 3
使用
handoff
且有
restore-hook: on
内容块 1(末尾带文件路径)、内容块 3。回执行应说明续接提示词已保存,并会在压缩后自动回到对话中
内容块 3 是供新会话使用的一句话:
读取 <path> 并从那里继续。
下一个任务是否与当前工作无关? 增加一行说明:最好使用
/clear
开启一个全新会话,并使用内容块 2 或内容块 3。全新会话的成本低于压缩,而且不会携带不需要的摘要。

Self-check before printing

输出前自检

  • Every dead end and every decision has a reason
  • Block 2 is understandable to a session that did not see the conversation
  • The compact line does not describe state
  • Up to 60 and 200 words, and up to 3 next steps
  • Exact strings were copied word for word, and secrets were replaced with
    [REDACTED]
  • No detail was invented about a part that was compacted

  • 每个失败路径和每项决策都有原因
  • 未看到原对话的会话也能理解内容块 2
  • 压缩命令没有描述当前状态
  • 分别不超过 60 个词和 200 个词,且下一步最多有 3 项
  • 精确字符串已逐字复制,秘密已替换为
    [REDACTED]
  • 没有编造有关已压缩内容的任何细节

Example

示例

In another language, the blocks keep this shape with the labels and the prose in that language.
text
/compact Keep: why the checkouts/update webhook was rejected (it fired dozens of times
per cart and created duplicate emails), the exact wording of the 429 error from
Klaviyo, and the user's correction: "never send to real customers in tests". You can
compress the JSON debugging round and the log reading.
text
Continue where we left off.

Building: an automatic abandoned cart email for a Shopify store.
State: the function in jobs/cart.ts is written and tested on a demo cart. Not tested against real Klaviyo, not deployed.
Decisions: Klaviyo and not Mailchimp, because Klaviyo has a built-in cart event.
Failed, don't retry: the checkouts/update webhook (it fired dozens of times per cart,
  created duplicate emails). Error: `429 Too Many Requests: rate limit 75/s exceeded`.
Rules set: never send to real customers in tests, only to the test address.
Read before touching: docs/DECISIONS.md
Next up: 1) deploy to staging  2) test on the test address  3) show me before turning it on.

使用另一种语言时,内容块仍保持这种结构,标签和叙述使用该语言。
text
/compact 保留:为何 checkouts/update webhook 被拒绝(每个购物车触发了几十次,造成重复邮件),Klaviyo 429 错误的准确措辞,以及用户的纠正:“never send to real customers in tests”。可以压缩 JSON 调试往返过程和日志读取。
text
从上次中断处继续。

构建中:为 Shopify 商店实现自动弃购邮件。
状态:jobs/cart.ts 中的函数已编写,并已使用演示购物车测试。尚未针对真实 Klaviyo 测试,也未部署。
决策:选择 Klaviyo 而不是 Mailchimp,因为 Klaviyo 内置购物车事件。
失败,不要重试:checkouts/update webhook(每个购物车触发了几十次,造成重复邮件)。错误:`429 Too Many Requests: rate limit 75/s exceeded`。
既定规则:测试时绝不向真实客户发送,只发送到测试地址。
修改前先阅读:docs/DECISIONS.md
下一步:1) 部署到 staging  2) 使用测试地址测试  3) 启用前先给我看。

Accuracy contract

准确性约定

Knows: the content of the current conversation, tool output that ran in the session, files you read in this run.
Does not know (a tool is required):
  • The date:
    date
    in step 1. Never from memory or from context.
  • What is already written in a target file:
    Read
    before writing. Never assume.
Asks when: an item looks like a decision but has no stated reason. Do not invent the reason. Ask in one line, or omit it.
Refuses when: asked to delete, compress or "clean up" existing content in the documentation files, or when the conversation was already compacted, there is no handoff file, and details are requested about what was compacted. Say so explicitly instead of making it up.

已知:当前对话的内容、会话中运行过的工具输出,以及本次运行中读取过的文件。
未知(需要使用工具):日期。必须在第 1 步执行
date
,绝不能凭记忆或上下文推断。
  • 目标文件中已经写入的内容:写入前必须执行
    Read
    ,绝不能假设。
需要询问时:某一项看起来是决策,但没有说明原因。不要编造原因。用一行询问,或者省略该项。
拒绝执行时:要求删除、压缩或“清理”现有文档文件中的内容;或者对话已经压缩过、不存在交接文件,却要求提供已压缩内容的详细信息。此时应明确说明,而不是凭空补全。

Boundaries

边界

Allowed: read the conversation. The step 1 command. Read files at known paths (target files, the handoff file,
config.md
). Print the blocks. Write only in the modes that were requested, and only to the step 4 targets.
Forbidden: running
/compact
yourself (the user pastes it or presses Smart compact; running it wipes their context). Searching for files or folders. Creating files or folders in the project. Writing when no write mode was requested. Rewriting or deleting existing lines, except the two exceptions in 4a. Copying a secret into a block or a file. Inventing a reason for a decision that was not explained. The skill itself does not commit or push. A separate user request to commit is handled as usual, after the blocks.
允许:读取对话;执行第 1 步命令;读取已知路径下的文件(目标文件、交接文件、
config.md
);打印内容块;仅在明确请求的模式下,向第 4 步指定的目标写入内容。
禁止:自行运行
/compact
(由用户粘贴命令或点击 Smart compact;自行运行会清除上下文);搜索文件或文件夹;在项目中创建文件或文件夹;未请求写入模式时执行写入;重写或删除已有行,但第 4a 节列出的两种例外除外;将秘密复制到内容块或文件中;为用户未解释原因的决策编造理由。该 skill 本身不会执行
commit
或
push
。用户另行提出提交请求时,仍按正常流程在输出内容块后处理。