12 KiB
name, description
| name | description |
|---|---|
| sessions | 搜索并询问关于 Claude Code、Codex 和 Cursor 中编码代理会话历史的问题。当需要了解之前做过什么、之前尝试过什么、跨会话如何调查一个问题、最近发生了什么,或任何关于过去代理会话的问题时使用。当用户提及先前的会话、之前的尝试或过去的调查时也可使用——即使没有明确提到'sessions'一词。 |
/sessions(从 EveryInc/compound-engineering-plugin ce-sessions 安装)
跨 Claude Code、Codex 和 Cursor 搜索会话历史,综合总结之前处理过、尝试过、决定过或学到过的内容。
用法
/ce-sessions [问题或主题]
/ce-sessions
预解析上下文
Git 分支(预解析): !git rev-parse --abbrev-ref HEAD 2>/dev/null || true
如果上述行解析为一个简单的分支名(如 feat/my-branch),则将其用于分支过滤,并传递给综合子代理。如果它仍然包含反引号命令字符串或为空,则在运行时推导分支名。
仓库名称(预解析): !basename "$(git rev-parse --show-toplevel 2>/dev/null)" 2>/dev/null || true
如果上述行解析为一个简单的仓库文件夹名,则将其用于会话发现。否则在运行时推导。
注意:2026 年
当前年份是 2026 年。在解释会话时间戳时使用此信息。
防护规则
以下规则在编排和综合过程中始终适用。
- 绝不要将会话文件整体读入上下文。 会话文件可能达到 1-7MB。始终先使用提取脚本进行过滤,然后在过滤后的输出上进行分析。
- 绝不要逐字提取或复现工具调用的输入/输出。 只需总结尝试了什么以及发生了什么。
- 绝不要包含思考或推理块的内容。 Claude Code 思考块是内部推理;Codex 推理块已加密。两者均不可操作。
- 绝不要分析当前会话。 其对话历史已对调用者可用。
- 呈现技术内容,而非个人内容。 会话包含所有内容——凭据、情绪、不成熟的意见。请自行判断哪些内容属于技术总结,哪些不属于。
- 访问出错时快速失败。 如果由于权限问题导致会话发现失败,立即报告问题。不要使用不同的工具或方法重试同一操作——重复重试只会浪费 token 而不会改变结果。
执行
如果未提供问题参数,则询问用户想了解会话历史中的什么内容。使用平台的阻塞式提问工具:Claude Code 中的 AskUserQuestion(如果其 schema 尚未加载,先调用 ToolSearch 并指定 select:AskUserQuestion),Codex 中的 request_user_input,Gemini 中的 ask_user,Pi 中的 ask_user(需要 pi-ask-user 扩展)。仅当阻塞式工具在 harness 中不存在或调用出错时(如 Codex 编辑模式),才回退到纯文本提问。绝不要因需要加载 schema 而静默跳过提问。
第 1 步——确定扫描窗口
从用户的问题推断时间范围。从窄窗口开始;仅在窄窗口未找到相关内容时才扩大窗口。
| 信号 | 初始扫描窗口 |
|---|---|
| "今天"、"今天上午" | 1 天 |
| "最近"、"最近几天"、"这周"、或未给出时间信号 | 7 天 |
| "最近几周"、"这个月" | 30 天 |
| "最近几个月"、广泛的功能历史 | 90 天 |
Claude Code 默认保留约 30 天的会话历史。除非用户延长了保留期限,否则更宽的窗口可能在 Claude Code 上找不到任何内容。
第 2 步——发现会话并提取元数据
运行发现 + 元数据管道(保留空分隔符 xargs 加固机制,使 extract-metadata.py 能以批处理模式运行):
bash scripts/discover-sessions.sh <repo> <days> | tr '\n' '\0' | xargs -0 python3 scripts/extract-metadata.py --cwd-filter <repo>
每行输出是一个描述会话的 JSON 对象(平台、文件、大小、时间戳、会话 ID,以及平台特定字段)。最后的 _meta 行携带 files_processed 和 parse_errors。
如果清单的 _meta 行显示 files_processed: 0,则返回"未找到相关先前的会话"并停止。
如果 parse_errors > 0,则注明部分会话无法解析,并继续处理已返回的内容。
要缩小平台范围,可在 discover-sessions.sh 调用中添加 --platform claude、--platform codex 或 --platform cursor。默认包含所有三个平台。
第 3 步——过滤和排序
按顺序应用以下过滤器,筛选出值得深入分析的会话:
-
分支过滤器(仅 Claude Code)。 保留
branch == dispatch_branch精确匹配的会话,或分支名包含问题主题关键词的会话(例如,关于"auth 中间件"的问题匹配feat/auth-fix、chore/auth-refactor等分支)。Codex 会话不携带gitBranch——跳过此过滤器。 -
如果分支过滤器返回零个会话,或者你在处理 Codex 会话:
- 从问题主题中推导出 2-4 个关键词。例如,对于"auth 中间件中 session-validation 拒绝有效 token 导致最近崩溃"的问题,推导出
auth,middleware,session,token(或类似关键词)。 - 重新运行发现管道,在
extract-metadata.py调用后追加--keyword K1,K2,...。脚本返回match_count非零的会话以及每个关键词的计数。 - 如果
files_matched: 0,则返回"未找到相关先前的会话"并停止。 不要提取任何内容。 - 如果
files_matched > 0,则将这些会话视为候选。按match_count排序,平局时按每个关键词的计数排序。
- 从问题主题中推导出 2-4 个关键词。例如,对于"auth 中间件中 session-validation 拒绝有效 token 导致最近崩溃"的问题,推导出
-
删除扫描窗口之外的会话。 优先使用
last_ts,回退到ts。丢弃两个时间戳都在窗口开始之前的会话。 -
排除当前会话——其对话历史已对调用者可用。
-
应用深度分析上限。 在所有平台中最多取 5 个会话。按分支匹配 →
match_count→ 文件大小 > 30KB → 最近时间排序。 -
过滤后至少保留一个会话时才继续。 否则返回"未找到相关先前的会话"并停止。
注意:gitBranch 仅在第一条用户消息时捕获。 一个从 main 开始、通过会话中途的 git checkout 在功能分支上完成实质性工作的会话,记录的是 branch: "main"。分支匹配返回空并不是结论性证据——这就是第 2 步中关键词过滤回退机制存在的原因。
第 4 步——设置临时工作空间
为每次运行创建一个一次性临时工作目录:
SCRATCH=$(mktemp -d -t ce-sessions-XXXXXX)
捕获绝对路径;将其传入第 5 步和第 6 步。操作系统会在会话结束时处理清理工作;在第 7 步末尾显式执行 rm -rf "$SCRATCH" 也无害,且能使意图更明确。
第 5 步——提取每个会话的内容(文件中介)
对每个选中的会话,使用 --output 运行骨架提取器,使内容直接写入临时文件——提取的字节不会通过编排器的工具结果往返传输:
python3 scripts/extract-skeleton.py --output "$SCRATCH/<session-id>.skeleton.txt" < <session-file>
标准输出仅接收一行 JSON 状态({"_meta": true, "wrote": "...", "bytes": N, ...})。从每个状态行捕获 bytes 和 parse_errors。
条件性尾部提取——如果骨架在调查中途结束(最后一个可见轮次是一个没有解决方案的工具调用,或代理在没有结论的情况下进行调试),则使用 tail 格式重新提取:
python3 scripts/extract-skeleton.py --output "$SCRATCH/<session-id>.skeleton.tail.txt" < <session-file>
(骨架脚本本身不直接接受 tail:N 上限;如果需要仅尾部视图,可在提取后通过 tail -n 50 在 shell 中后处理临时文件。仅在头部输出表明会话在调查中途被截断时使用此方法。)
条件性错误模式——对于调查死胡同可能有价值的会话:
python3 scripts/extract-errors.py --output "$SCRATCH/<session-id>.errors.txt" < <session-file>
有选择地使用——仅当了解出了什么问题能增加价值时才使用。Cursor 代理记录不记录工具结果,因此错误模式对 Cursor 会话不会产生任何内容。
第 6 步——调度综合子代理
通过平台的子代理原语(Claude Code 中的 Agent,Codex 中的 spawn_agent,Pi 中的 subagent,需要 pi-subagents 扩展)调度 ce-session-historian 子代理。省略 mode 参数,以便应用用户配置的权限设置。在中档模型上运行(例如 Claude Code 中的 model: "sonnet")——合成器不需要前沿推理能力。
调度提示是代理的输入合约。传递以下字段:
problem_topic——用一句话描述具体问题。从用户参数中提取,如果未提供,则从无参数提示的答案中提取。scratch_dir——$SCRATCH的绝对路径。sessions——对象数组,每个提取的会话对应一个,包含:path——骨架文件的绝对路径(以及提取了错误文件时的errors_path)platform——claude、codex或cursorbranch——存在时的 git 分支(仅 Claude Code)cwd——存在时的工作目录(仅 Codex)ts和last_ts——会话时间戳match_count和keyword_matches——使用关键词过滤时
output_schema——代理响应的结构。默认 schema:当调用者(如将你的响应组织为以下章节(如无发现则省略对应章节): - 之前尝试过的内容 - 哪些方法无效 - 关键决策 - 相关上下文ce-compound)在技能参数中提供了 schema,则逐字传递。
调度示例格式:
综合来自这些先前会话的发现:
问题主题:<一行主题>
要读取的会话($SCRATCH 中的路径):
1. /tmp/ce-sessions-XXXX/abc123.skeleton.txt
platform=claude branch=feat/auth-fix ts=2026-05-01
2. /tmp/ce-sessions-XXXX/def456.skeleton.txt errors=/tmp/ce-sessions-XXXX/def456.errors.txt
platform=codex cwd=/Users/.../my-project ts=2026-05-03
...
输出 schema:
- 之前尝试过的内容
- 哪些方法无效
- 关键决策
- 相关上下文
过滤规则:仅呈现与此特定问题直接相关的发现。
忽略来自同一会话或分支的无关工作。
代理通过平台的原生文件读取工具读取每个路径,并返回散文格式的发现。批量提取内容仅存在于代理的子代理上下文中——编排器的工作状态仅保留文件路径和小型清单元数据。
第 7 步——返回发现
将合成器的输出文本逐字返回给调用者。如果发现或关键词过滤返回了零个会话(第 2 步或第 3 步),则改为返回字面字符串 no relevant prior sessions。
可选地清理临时空间:
rm -rf "$SCRATCH"
操作系统最终无论如何都会处理清理工作;显式清理是为了期望看到它的读者。
输出
当调用者(通常是输入 /ce-sessions 的用户,或通过平台技能调用原语调用 ce-sessions 的其他技能)未指定输出格式时,应包含一个简要的头部说明搜索范围:
**搜索的会话**: [数量]([N] 个 Claude Code,[N] 个 Codex,[N] 个 Cursor)| [日期范围]
然后是合成器的散文式发现。当调用者提供了 schema 时,逐字遵循该 schema,并省略默认头部。
时间预算
一旦获得完整答案,立即停止。如果在几秒钟内就能自信地得出"未找到相关先前的会话",这本身就是一个完整的答案;不要为了填满时间而延长搜索。第 3 步中的结构性上限(最多深度分析 5 个会话)和第 5 步中的条件性尾部/错误提取机制从结构上限制了运行时间。
错误处理
如果发现管道失败(例如,家目录不可读、权限失败),将错误呈现给调用者。不要用 git 日志、文件列表或其他来源替代——此技能的合约是会话元数据和综合。
如果提取的 --output 写入失败(磁盘满、权限问题),呈现清晰的错误信息,且不要用不完整的路径调度合成器。
如果任何脚本的 _meta 报告 parse_errors > 0,在调度提示中注明部分提取情况,然后继续处理;合成器会在发现中标记不完整的情况。