アルアカ - Arcadia Academia

Arcadia Academiaは「エンジニアリングを楽しむ」を合言葉に日本のデジタル競争力を高めることをミッションとするテックコミュニティです。

Claude Codeの過去セッションが--resumeに出ない原因はcleanupPeriodDays(既定30日)

Featured image of the post

「先月やった作業の続きを claude --resume で開こうとしたら、一覧に出てこない」「~/.claude/projects/ を見に行ったら、古い .jsonl がきれいに無くなっている」「保持期間を延ばしたいけれど、ディスクがどれだけ膨らむのか読めない」。

Claude Code は会話の記録(トランスクリプト)をローカルに保存していますが、既定では30日を過ぎたものが自動で削除されます。設定ファイルにキーが書かれていないだけで既定値が働いているので、消えるまで気づけません。この記事では、消えた原因の確かめ方、保持期間の延ばし方、そして期間を延ばしたときにディスクを圧迫する「自動起動セッション」だけを見分けて掃除する手順をまとめます。

💡
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日あたりのセッション数 × 延ばす日数」を掛けたものが増分の目安です。自動起動が多い環境ほど、この記事の掃除スクリプトと組み合わせる効果が大きくなります。

プログラミング学習でお悩みですか?

現役エンジニアがあなたの学習をマンツーマンでサポートします。

  • 学習の進め方がわからない
  • ポートフォリオの作り方を知りたい
  • 現場で使える技術を学びたい
まずは30分の無料相談

相談は完全無料・オンラインで気軽に

あなたを爆速で成長させるメンタリングプログラムはこちら

メンタープログラムバナー

学習・開発のお悩みは現役エンジニアに相談

メンタープログラムの詳細を見る

エンジニアの基礎学習ゲーム

プログラミング学習支援

無料相談はこちら