mcpField
F
find-past-conversation

find-past-conversation

github.com/donnfelkerAgent 工作流4764 次安装19 周前更新
代码仓库

关于 find-past-conversation

这项 Claude Code 技能帮助用户从本地会话记录中找回过去的对话,适用于记得主题但需要定位具体会话的人。它指导按项目和关键词筛选 JSONL 记录,并提取会话标识、时间及讨论摘要。

主要功能

  1. 01按项目目录定位会话
  2. 02使用 ripgrep 搜索关键词
  3. 03跳过子 Agent 记录以减少重复
  4. 04从 JSONL 中提取有限上下文
  5. 05汇报会话标识、时间和摘要

适用场景

  1. 01找回关于特定主题的 Claude Code 对话
  2. 02确认过去会话讨论过的决定
  3. 03定位可能完成某项工作的会话
  4. 04从记录中核查分支、提交或 PR

安装

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

$npx skills add https://github.com/donnfelker/donnfelker-plugin-marketplace --skill find-past-conversation

安装后在 Claude Code 中输入/find-past-conversation确认已加载。

详细介绍

查找以前的 Claude Code 对话

你正在帮助用户回忆以前的 Claude Code 会话。他们大致记得讨论过什么,希望你找到实际的对话记录——会话 ID、发生时间、简短摘要,以及(如有相关内容)最终交付了什么。

Claude Code 会将每个会话保存为 ~/.claude/projects/ 下的 JSON-lines 文件。本技能将介绍如何高效搜索这些对话记录,避免因读取数兆字节的日志文件而耗尽上下文。

何时使用此技能

遇到以下类似说法时触发:

  • “搜索你的历史记录,查找关于 [主题] 的内容”
  • “找出我们之前关于 [主题] 的对话”
  • “翻翻你过去的会话,看看有没有关于 [主题] 的内容”
  • “我有没有完成过关于 [主题] 的工作?”
  • “我们上周对 [主题] 作了什么决定?”
  • “提醒我一下,[主题] 那次会话最后得出了什么结果”

不要用此技能搜索当前代码库、当前 PR 的评论或 Slack/Jira 等外部系统——这些各有自己的技能和工具。

对话记录的组织方式

~/.claude/projects/
├── -Users-alice-source-acme-api/
│   ├── 06c5c59e-0735-...jsonl          # one session = one file
│   ├── a7e955d8-cf10-...jsonl
│   └── a7e955d8-cf10-.../
│       └── subagents/
│           └── agent-ab42fde6...jsonl  # subagent transcripts
├── -Users-alice-source-acme-worker/
└── ...

重要事项:

  • **项目文件夹名称是工作目录将 / 替换为 - 后的结果。**例如,在 /Users/alice/source/acme/api 中运行的会话,其文件位于 ~/.claude/projects/-Users-alice-source-acme-api/ 下。
  • 会话 ID 是不含 .jsonl 的文件名,例如 a7e955d8-cf10-42ec-a36b-0fe2bcb42d45。
  • .jsonl 中的每一行都是一条独立的 JSON 消息,包含 type 字段(user、assistant、system 等)、timestamp 和内容。每行都没有格式化,长度可能达到数十 KB。
  • **子 Agent 的对话记录位于 <session-id>/subagents/agent-*.jsonl。**其中噪声较多,还会增加命中数,却没有太大帮助。默认跳过。

搜索流程

第 1 步 — 选择正确的项目文件夹

如果用户当前在某个仓库中工作,而且他们记得的会话就在该仓库中,就从这里开始。根据当前工作目录计算项目文件夹:

ENCODED=$(pwd | sed 's|/|-|g')
ls ~/.claude/projects/$ENCODED/*.jsonl 2>/dev/null | wc -l

如果用户想在所有工作中查找(例如“我们以前在什么地方讨论过 X 吗?”),就搜索所有项目:

ls -d ~/.claude/projects/*/

拿不准时就问:“那次对话是在这个仓库里,还是涉及你所有的工作?”——事先缩小范围可以节省时间并减少误报。

第 2 步 — 使用 ripgrep 定向搜索

在项目文件夹中使用 rg。绝不要 cat 整个 .jsonl 文件——这些文件通常有数兆字节,而且包含带有加密签名的大段模型思考内容,会耗尽上下文。

rg -l -i "<distinctive phrase>" ~/.claude/projects/<project>/*.jsonl

-l(仅列出文件)是正确的第一步——你只需要找到候选文件。缩小范围后,再进行第二轮检查内容。

**注意搜索词的选择。**常见词会产生很多噪声:

  • auto-approve → 会匹配每个使用了 terraform apply -auto-approve 的 CI 工作流
  • commit → 会匹配每个会话中的所有 git 提交消息
  • error → 会匹配每条重试过的 bash 命令

如果用户只提供了一个通用词,搜索前先请他们提供一个有辨识度的短语:错误字符串、函数名称、标志、文件路径、UI 标签或人名。一个具体短语胜过五个通用词。

子 Agent 的对话记录位于更深一层(<project>/<session-id>/subagents/agent-*.jsonl),因此顶层 shell glob(如 ~/.claude/projects/<project>/*.jsonl)会自动跳过它们——针对这种情况无需额外标志:

rg -l -i "your phrase" ~/.claude/projects/<project>/*.jsonl

如果改用 ripgrep 递归搜索所有内容(例如不知道项目在哪),请明确排除子 Agent 目录树,否则会得到重复命中:

rg -l -i "your phrase" ~/.claude/projects \
   --glob '*.jsonl' --glob '!**/subagents/**'
第 3 步 — 筛选候选列表
  • 0 个命中 → 告知用户,并请他们提供更有辨识度的短语。不要继续猜测同义词。
  • 1–3 个命中 → 很好,逐一检查。
  • 4 个或更多命中 → 请用户提供第二个缩小范围的词,或按最近时间排序,优先查看最新记录(ls -lt)。
步骤 4 — 提取上下文,识别 JSON

对于每个候选文件,使用有界窗口提取周边上下文。以下两种模式都很实用:

模式 A — grep 并显示行上下文(快速、粗略):

rg -i -B 2 -A 5 "your phrase" ~/.claude/projects/<project>/<session>.jsonl | head -100

这会捕获每个匹配项周围数百行原始 JSON。适合快速目视检查。

模式 B — 识别 JSON 结构后提取(更整洁):

rg -i "your phrase" ~/.claude/projects/<project>/<session>.jsonl | \
  jq -r 'select(.type=="user" or .type=="assistant") |
         "\(.timestamp) [\(.type)] \(.message.content // .content | tostring | .[0:300])"'

这会筛选出仅包含用户/助手的轮次,并打印时间戳和前 300 个字符。除非 tool_use 和 tool_result 条目与用户搜索的内容直接相关,否则跳过它们——这些条目内容很多,而且很少能提供答案。

步骤 5 — 报告发现

对于每个有力的候选项,列出:

  • 会话 ID(不含 .jsonl 的文件名)
  • 项目文件夹(~/.claude/projects/<encoded>)
  • 日期/时间(使用匹配消息上的时间戳;若没有,则使用文件的修改时间)
  • 2-4 句摘要,说明讨论和决定的内容

如果有多个候选项,逐一简要列出,让用户选择要深入查看哪一个。不要把 20 KB 的原始 JSON 一股脑贴进聊天中——用户要的是回顾摘要,而不是重读一遍。

报告结果(可选后续操作)

用户真正想问的往往是“我们最终发布了吗?”找到会话后,可以扫描转录内容,了解实际完成了什么:

# Branches created, commits made, PRs opened
rg -o '"command":"git (commit|push|checkout -b)[^"]*' <session>.jsonl
rg -o 'gh pr create[^"]*' <session>.jsonl
rg -o 'https://github.com/[^"]*pull/[0-9]+' <session>.jsonl | sort -u

如果找到 PR URL,请检查其当前状态:

gh pr view <N> --repo <owner>/<repo> --json number,title,state,mergedAt,reviewDecision,url

回复时报告:开放 / 已合并 / 已关闭、当前评审决定,以及 CI 最近一次是否通过。这通常才是用户真正想知道的答案。

应避免的反模式

  • 不要用 cat 读取整个 .jsonl 文件。 这些文件非常大,还包含 signature 块、base64 思维轨迹和工具结果负载。先用 rg 找到匹配行,再用 jq 或 grep -B/-A 提取窗口。
  • 不要在没有限定条件时搜索常见词。 approve、error、fix、commit、pr 会匹配到每个会话。围绕用户记得的独特内容进行搜索。
  • 不要轻信第一个匹配项。 会话可能持续数小时;关键决定往往出现在后续轮次。检查时间戳,优先选择会话末尾附近的匹配项,而不是开头附近的匹配项。
  • 不要自动包含子 Agent 的转录。 它们会从不同角度重复父会话的内容,并增加匹配项数量。递归时,使用 --glob '!**/subagents/**' 排除;使用顶层 Shell 通配符时,它们已经被跳过。
  • 不要凭记忆转述。 如果要报告讨论内容,每个说法都必须以从文件中提取的实际行作为依据——模型对过往会话的记忆并不可靠。
  • 如果用户已明确指出仓库,不要搜索整个 ~/.claude/projects/*。 先缩小搜索范围。

故障模式与恢复

  • 搜索没有结果。 请用户提供更具体的短语(错误消息、函数名、文件路径、人名)。如果用户只记得一个主题,尝试 2-3 个同义词变体——之后就停止并询问,不要没完没了地尝试模式匹配。
  • 匹配文件位于一个你从未见过的项目中。 这没问题——转录文件仍位于 ~/.claude/projects/<encoded-cwd>/。编码后的目录名会告诉你原始 cwd;如果需要检查仓库,可以切换到该目录。
  • 找到会话后,无法判断做出了什么决定。 阅读最后几轮用户消息,以及工具调用链结束前的最后一轮助手消息。决定通常在这些内容里,而不是漫长的调试对话中间。

示例

用户说:“找到我们讨论机器人发现有人批准 PR 后自动批准 PR 的那段对话。”

# Step 1: across all projects since user didn't name a repo.
# The shell glob `*/[0-9a-f]*.jsonl` only matches top-level session files,
# so subagent transcripts (one dir deeper) are naturally excluded.
rg -l -i "auto.approv" ~/.claude/projects/*/[0-9a-f]*.jsonl
# → too many hits; mostly `terraform apply -auto-approve`. Ask for a distinctive phrase.

# User: "look for 'request changes'"
rg -l -i "request changes" ~/.claude/projects/*/[0-9a-f]*.jsonl
# → narrows to ~10 files. Sort by recency.

ls -lt $(rg -l -i "request changes" ~/.claude/projects/*/[0-9a-f]*.jsonl) | head -5

# Step 4: read context from the most recent candidate
rg -i -B 2 -A 5 "request changes" \
   ~/.claude/projects/-Users-alice-source-acme-api/a7e955d8-*.jsonl | head -60

# Step 5: report — Session a7e955d8-... in acme-api, 2026-05-14, about the review bot
#   posting a plain comment after a REQUEST_CHANGES review (which doesn't clear the
#   block) instead of submitting a new opinionated review.

# Outcome check
rg -o 'https://github.com/[^"]*pull/[0-9]+' \
   ~/.claude/projects/-Users-alice-source-acme-api/a7e955d8-*.jsonl | sort -u
# → https://github.com/acme/api/pull/23
gh pr view 23 --repo acme/api --json state,mergedAt,reviewDecision
# → OPEN, APPROVED, not yet merged

用户会得到一条简洁的答复:会话 ID、日期、摘要,以及“PR #23 — 已批准,但尚未合并。”

评论

支持 Markdown