find-past-conversation について
ローカルのセッション記録から過去の会話を探す Claude Code スキルです。話題は覚えているものの該当するセッションを特定したい場合に、プロジェクトや語句で JSONL を検索し、ID、日時、要約を取り出します。
主な機能
- 01プロジェクトディレクトリからセッションを特定
- 02ripgrep による語句検索
- 03重複を減らすサブエージェント記録の除外
- 04JSONL から範囲を絞った文脈を抽出
- 05セッション ID、日時、要約の報告
活用シーン
- 01話題に関する Claude Code の会話を検索
- 02過去のセッションでの決定を確認
- 03作業完了の可能性があるセッションを特定
- 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 ファイルとして保存します。このスキルでは、数メガバイトのログファイルでコンテキストを浪費せずに、これらのトランスクリプトを効率よく検索する方法を説明します。
このスキルを使うタイミング
次のようなフレーズがあった場合に使用します。
- 「[topic]について履歴を検索して」
- 「[topic]について話した会話を見つけて」
- 「[topic]について過去のセッションを調べて」
- 「[topic]の作業は最後まで終わらせたっけ」
- 「先週、[topic]について何を決めたっけ」
- 「[topic]のセッションで何ができたか思い出させて」
現在のコードベース、現在の 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の各行は、typeフィールド(user、assistant、systemなど)、timestamp、内容を含む単一の JSON メッセージです。 行は整形されておらず、1 行が数十 KB に及ぶこともあります。- サブエージェントのトランスクリプトは
<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 を使います。.jsonl ファイル全体を cat しないでください。ファイルは日常的に数メガバイトに達し、コンテキストを圧迫する暗号署名付きの大きなモデル思考ブロックが含まれています。
rg -l -i "<distinctive phrase>" ~/.claude/projects/<project>/*.jsonl
まずは -l(ファイル名のみを出力)が適切です。候補ファイルだけを特定し、対象を絞った後の 2 回目の検索で内容を確認します。
検索語の選び方は重要です。 一般的な語はノイズを生みます。
auto-approve→terraform apply -auto-approveを含む CI ワークフローすべてに一致しますcommit→ すべてのセッションにあるあらゆる git コミットメッセージに一致しますerror→ 再試行されたすべての bash コマンドに一致します
ユーザーが一般的な語しか挙げていない場合は、検索する前に特徴的なフレーズを尋ねてください。エラーメッセージ、関数名、フラグ、ファイルパス、UI ラベル、人物名などが使えます。具体的なフレーズ 1 つのほうが、一般的な語 5 つより効果的です。
サブエージェントのトランスクリプトは 1 階層深い場所(<project>/<session-id>/subagents/agent-*.jsonl)にあるため、~/.claude/projects/<project>/*.jsonl のようなトップレベルのシェルグロブでは自動的に除外されます。対象を絞った検索では、追加のフラグは必要ありません。
rg -l -i "your phrase" ~/.claude/projects/<project>/*.jsonl
代わりに ripgrep で全体を再帰検索する場合(プロジェクトがわからないときなど)は、サブエージェントのサブツリーを明示的に除外してください。そうしないと、重複した検索結果が表示されます。
rg -l -i "your phrase" ~/.claude/projects \
--glob '*.jsonl' --glob '!**/subagents/**'
ステップ 3 — 候補リストを確認する
- ヒット数が 0 件 → ユーザーに伝え、より特徴的なフレーズを尋ねます。同義語を推測し続けないでください。
- ヒット数が 1〜3 件 → 最適です。それぞれを確認します。
- ヒット数が 4 件以上 → さらに絞り込む語を尋ねるか、更新日時の新しい順に並べて最近のものから確認します(
ls -lt)。
Step 4 — コンテキストを抽出する(JSON 対応)
候補となる各ファイルについて、範囲を限定して前後のコンテキストを取得します。次の 2 つの方法が有効です。
パターン 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 のエントリは省略してください。これらは量が多く、答えになることはほとんどありません。
Step 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 が最後に成功していたかどうかを伝えてください。通常、ユーザーが本当に知りたかったのはこの点です。
避けるべきアンチパターン
.jsonlファイル全体をcatしないでください。 ファイルは巨大で、signatureブロック、base64 形式の思考トレース、ツール結果のペイロードが含まれています。まずrgで一致する行を探し、次にjqまたはgrep -B/-Aで前後の範囲を取得してください。- 条件を付けずに一般的な単語を grep しないでください。
approve、error、fix、commit、prは、どのセッションにもヒットします。ユーザーが覚えている特徴的な語句を軸に検索してください。 - 最初の一致を鵜呑みにしないでください。 セッションは数時間続くことがあります。正式な決定は後のターンにある場合が多いため、タイムスタンプを確認し、セッションの最初よりも最後に近い一致を優先してください。
- サブエージェントのトランスクリプトを自動で含めないでください。 親セッションの内容を別の視点から重複して記録したもので、ヒット数が増えてしまいます。再帰的に検索する場合は、
--glob '!**/subagents/**'で除外してください。トップレベルのシェル glob を使う場合は、すでに除外されています。 - 記憶を頼りに言い換えないでください。 話し合った内容を報告する場合は、抽出した実際の行をすべての主張の根拠にしてください。過去のセッションに関するモデルの記憶は信頼できません。
- ユーザーがリポジトリを明示している場合に、
~/.claude/projects/*全体を検索しないでください。 まず対象を絞ってください。
失敗した場合の対処
- 検索結果が何もない。 エラーメッセージ、関数名、ファイルパス、人名など、より具体的な語句をユーザーに尋ねてください。トピックしか覚えていない場合は、同義語を 2〜3 通り試します。それ以上は続けず、パターンマッチングを延々と続けるのではなく、ユーザーに尋ねてください。
- 一致したファイルが、見たことのないプロジェクトにある。 問題ありません。トランスクリプトは
~/.claude/projects/<encoded-cwd>/にあります。エンコードされたディレクトリ名から元の cwd が分かるので、リポジトリを調べる必要があれば、そこへcdできます。 - セッションは見つかったが、何が決まったのか分からない。 最後の数回のユーザーターンと、ツール使用の連鎖が終わる直前の最後のアシスタントターンを読んでください。決定事項は通常、長いやり取りの途中ではなく、これらの中にあります。
実例
ユーザーの依頼:「承認が見つかったときに、ボットが 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 — 承認済みだがマージされていない」という要点をまとめた回答を提示します。