「先月やった作業の続きを claude --resume で開こうとしたら、一覧に出てこない」「~/.claude/projects/ を見に行ったら、古い .jsonl がきれいに無くなっている」「保持期間を延ばしたいけれど、ディスクがどれだけ膨らむのか読めない」。
Claude Code は会話の記録(トランスクリプト)をローカルに保存していますが、既定では30日を過ぎたものが自動で削除されます。設定ファイルにキーが書かれていないだけで既定値が働いているので、消えるまで気づけません。この記事では、消えた原因の確かめ方、保持期間の延ばし方、そして期間を延ばしたときにディスクを圧迫する「自動起動セッション」だけを見分けて掃除する手順をまとめます。
- トランスクリプトは
~/.claude/projects/<プロジェクト>/<セッションID>.jsonl に保存され、cleanupPeriodDays が未設定なら 30日で削除される - 消えたものは
--resume でも開けない。find で最古のファイル日付を見て「ちょうど30日前」なら確定 - 延ばすなら
~/.claude/settings.json に "cleanupPeriodDays": 90 を追加する -
claude -p や SDK から起動したセッションは先頭の user 行に entrypoint が sdk-cli と記録され、人が打ったセッション(cli)と機械的に分けられる - 手元の実測では自動起動が全体の94%を占めた。期間を延ばすなら、自動セッションだけ短い期限で掃除する
目次を開く
まず「消えている」ことを確かめる
最古のトランスクリプトの日付を見る
find ~/.claude/projects -name '*.jsonl' -printf '%TY-%Tm-%Td\n' | sort | head -1 表示された日付が実行日のちょうど30日前で、それより前のファイルが1つも無ければ、既定値による削除で確定です。手元の環境でも最古のファイルは実行日の30日前で、それ以前は1本も残っていませんでした。
設定にキーがあるか見る
grep -n cleanupPeriodDays ~/.claude/settings.json || echo "未設定(既定の30日が適用)" 消えると何ができなくなるか
-
claude --resumeの一覧に出ない。セッションIDを直接指定しても開けない - 履歴を読み取る自作ツール(セッションモニターなど)にも出ない。ファイルそのものが無いので、ツール側では検知できない
- 知見の抽出やログの掘り直しを後からやろうとしても、30日を過ぎた分は原理的に不可能
保持期間を延ばす
~/.claude/settings.json にキーを1つ足します。他のキーがある場合はカンマの位置に注意してください。
{
"cleanupPeriodDays": 90
} 書き換えた後は JSON として壊れていないかを確認します。
python3 -m json.tool ~/.claude/settings.json > /dev/null && echo OK 延ばす前にディスクを見る
トランスクリプトは会話の全文とツールの出力を含むので、1本あたりが大きくなりがちです。延ばす前に現状を数えておきます。
du -sh ~/.claude/projects
find ~/.claude/projects -name '*.jsonl' | wc -l 手元の実測(30日分)は次のとおりでした。
| 項目 | 値 |
|---|---|
| ファイル数 | 1,563 |
| 合計サイズ | 1.8GB |
| 人が端末で打ったセッション | 88本(6%) |
自動起動(claude -p・SDK・cron 由来) | 94% |
90日に延ばせば単純計算で3倍です。しかも大半が人の目に触れない自動起動のセッションなので、延ばすなら自動側だけを別の期限で消す運用が筋です。
人間のセッションと自動起動を見分ける
各トランスクリプトの最初の user 行には、起動経路のメタデータが入っています。
| キー | 人が端末で打った | 自動起動 |
|---|---|---|
entrypoint | cli | sdk-cli |
promptSource | typed | sdk または無し |
origin.kind | human | 無し |
メタデータが無い古い形式のセッションは「人間」として扱います。誤って人の会話を消すほうが、自動が混ざるより害が大きいためです。
起動経路を集計するスクリプト
先頭60行しか読まないので、1,500本・1.8GB でも1秒かかりません。
#!/usr/bin/env python3
"""transcript_kind.py: トランスクリプトの起動経路を集計・列挙・掃除する。"""
import argparse, pathlib, re, time
ROOT = pathlib.Path.home() / ".claude" / "projects"
PAT = re.compile(r'"entrypoint"\s*:\s*"([^"]+)"')
def kind_of(path):
"""先頭60行から entrypoint を拾う。無ければ human 扱い"""
with path.open(encoding="utf-8", errors="replace") as fp:
for i, line in enumerate(fp):
if i >= 60:
break
m = PAT.search(line)
if m:
return m.group(1)
return "cli"
ap = argparse.ArgumentParser()
ap.add_argument("--kind", help="この起動経路だけ対象にする(例: sdk-cli)")
ap.add_argument("--older-than", type=int, default=0, help="この日数より古いものだけ対象にする")
ap.add_argument("--delete", action="store_true", help="実際に削除する(無ければ一覧のみ)")
args = ap.parse_args()
limit = time.time() - args.older_than * 86400
counts, targets = {}, []
for f in ROOT.rglob("*.jsonl"):
k = kind_of(f)
counts[k] = counts.get(k, 0) + 1
if (args.kind is None or k == args.kind) and f.stat().st_mtime < limit:
targets.append(f)
for k, v in sorted(counts.items(), key=lambda kv: -kv[1]):
print(f"{v:6d} {k}")
print(f"対象: {len(targets)} 本 / {sum(f.stat().st_size for f in targets) / 2**20:.1f} MB")
for f in targets:
print(("削除 " if args.delete else "候補 ") + str(f))
if args.delete:
f.unlink() 集計だけなら引数なしで実行します。
python3 transcript_kind.py 自動セッションだけ古いものを掃除する
まず消さずに一覧を出し、人の会話が混ざっていないか目で確かめます。
# 自動起動(sdk-cli)で14日より古いものを列挙するだけ。まだ消さない
python3 transcript_kind.py --kind sdk-cli --older-than 14 一覧に問題がなければ --delete を付けて実行します。消したものは戻らないので、--delete は必ず一覧を見た後にしてください。
python3 transcript_kind.py --kind sdk-cli --older-than 14 --delete この2段運用にしておけば、cleanupPeriodDays を90日や180日に延ばしても、ディスクを食うのは人の会話だけになります。
消えて困る会話は別の場所に写す
保持期間の設定とは別に、残したい会話は同期しておくと安心です。トランスクリプトには貼り付けたコードやツール出力が全文入るので、写し先はパーミッションを絞ります。
mkdir -p ~/backup/claude-transcripts && chmod 700 ~/backup/claude-transcripts
rsync -a --ignore-existing ~/.claude/projects/ ~/backup/claude-transcripts/ --ignore-existing にしておけば、元が削除されても写し先は残ります。cron に載せるなら1日1回で十分です。
まとめ
-
claude --resumeに古いセッションが出ないのは、cleanupPeriodDaysの既定30日で削除されているため。findで最古の日付を見れば確定できる - 延ばすのは
~/.claude/settings.jsonにキーを1行足すだけ。ただし延ばす前にduとwc -lで現状を数える - トランスクリプトの先頭行にある
entrypointで人間(cli)と自動(sdk-cli)を分けられる。自動側だけ短い期限で掃除すれば、期間を延ばしてもディスクは膨らまない - 消えたものは復元できない。残したい会話は
rsyncで別の場所へ写しておく
よくある質問(FAQ)
消えたセッションを復元できますか
できません。トランスクリプトの .jsonl が削除されると --resume の一覧からも消え、セッションIDを指定しても開けません。バックアップから ~/.claude/projects/ の同じパスに戻せば一覧に出ますが、写しが無い場合は諦めるしかありません。
人間のセッションだけ長く残す設定はありますか
手元の版では、本体の設定は日数1つだけで、起動経路ごとに期間を分ける項目はありませんでした。cleanupPeriodDays を長めにしたうえで、自動起動のセッションをこの記事のスクリプトで別に消す、という組み合わせで同じ効果が得られます。
sdk-cli とは何ですか
claude -p "..." のようなヘッドレス実行や、Agent SDK から起動したセッションに記録される起動経路の値です。cron や常駐スクリプトから Claude Code を呼んでいる環境では、この値のセッションが人の会話を圧倒的に上回ります。手元の実測では全体の94%でした。
保持期間を延ばすとディスクはどれくらい増えますか
現状の合計サイズをファイル数で割れば1本あたりの平均が出ます(手元では約1.2MB/本)。それに「1日あたりのセッション数 × 延ばす日数」を掛けたものが増分の目安です。自動起動が多い環境ほど、この記事の掃除スクリプトと組み合わせる効果が大きくなります。
