この記事は、OpenAI Codex CLIのTUI(ターミナルUI)で長い会話の過去ログがスクロールできなくなる問題の解決策をまとめたものです。 Google検索では「resume」が履歴書の意味に引っ張られて情報が見つからないため、ここに記録します。
この記事で解決できること
- Codex CLIで長時間作業していたら、過去の会話が画面から消えて見えなくなった
codex resumeでセッションを再開したが、最初の方のやり取りを確認したい- 過去のセッションからキーワードで会話を検索したい
- 会話履歴をテキストファイルとして保存・共有したい
結論:TUIのスクロールに期待するのが負け
Codex CLIのTUIは見た目はチャットですが、表示できるスクロール量には限界があります。長期戦になると過去ログが「物理的に掘れない」状態になります。
解決策は2つ:
- ローカルに保存されたログファイルを直接読む
- 端末の設定でスクロール上限を増やす
この記事では主に1の方法を詳しく解説します。
Codexのログはどこに保存されているか
Codex CLIは会話ログをローカルに自動保存しています。
~/.codex/sessions/YYYY/MM/DD/rollout-XXXX.jsonl
例:
~/.codex/sessions/2025/12/14/rollout-2025-12-14T11-00-35-019b1a96-986b-7e20-865e-db1aff031855.jsonl
このファイルはcodex resumeでセッションを選ぶときの対象にもなっています。
ログファイルの確認
ls ~/.codex/sessions/
# 年/月/日のディレクトリ構造
ls ~/.codex/sessions/2025/12/14/
# rollout-*.jsonl ファイルが並ぶ

JSONLファイルの構造を理解する
.jsonl(JSON Lines)は1行が1つのJSONオブジェクトになっている形式です。そのまま開くと非常に見にくいです。
必要なツール:jq
JSONを整形・抽出するためのコマンドラインツールです。
# インストール(Ubuntu/Debian)
sudo apt update && sudo apt install -y jq
ログの構造を確認する
まず、ログファイルのキー構造を確認します:
cd ~/.codex/sessions/2025/12/14
# ファイルを1つ選ぶ
f=$(ls -1 rollout-*.jsonl | head -n 1)
echo "FILE=$f"
# トップレベルのキーを確認
head -n 1 "$f" | jq 'keys'
出力例:
[
"payload",
"timestamp",
"type"
]
typeの種類を確認する
ログには複数の種類のイベントが混在しています:
jq -r '.type' "$f" | sort | uniq -c | sort -nr | head -n 30
出力例:
142 response_item
47 event_msg
12 turn_context
1 session_start
主要なtype:
event_msg: ユーザーの入力やシステムイベントresponse_item: AIの応答turn_context: コンテキスト情報session_start: セッション開始時のメタデータ

会話を見やすく抽出する
ユーザーの入力だけを抽出
jq -r '
select(.type=="event_msg" and .payload.type=="user_message")
| "USER: " + .payload.message
' "$f" | less -R
AIの応答だけを抽出
jq -r '
select(.type=="response_item")
| (.payload.role // "assistant") + ": " + ((.payload.content // []) | map(.text? // empty) | join(""))
' "$f" | less -R
会話全体をテキストファイルに変換
jq -r '
if .type=="event_msg" and .payload.type=="user_message" then
"USER: " + (.payload.message // "")
elif .type=="response_item" then
"ASSISTANT: " + ((.payload.content // []) | map(.text? // empty) | join(""))
else empty end
' "$f" > convo.txt
less -R convo.txt
タイムスタンプ付きで出力
jq -r '
select(.type=="event_msg")
| "[" + (.timestamp|tostring) + "] "
+ (.payload.type // "event") + ": "
+ (.payload.message // "")
' "$f" > convo_with_timestamp.txt
キーワードで過去の会話を検索する
複数のログファイルからキーワードを検索するにはripgrep(rg)が便利です。
# インストール
sudo apt install -y ripgrep
# 検索
cd ~/.codex/sessions
rg -n "Next\.js|マルウェア|脆弱性" --include "*.jsonl"
特定のディレクトリ内で検索:
cd ~/.codex/sessions/2025/12/14
rg -n "検索したいキーワード" rollout-*.jsonl
便利コマンドを作成する(道具化)
毎回jqのコマンドを打つのは面倒なので、スクリプト化しておくと便利です。
codexlogコマンドの作成
mkdir -p ~/bin
cat > ~/bin/codexlog <<'SH'
#!/usr/bin/env bash
set -euo pipefail
f="${1:-}"
if [[ -z "$f" ]]; then
f="$(ls -1t rollout-*.jsonl 2>/dev/null | head -n 1)"
fi
if [[ ! -f "$f" ]]; then
echo "Error: File not found: $f" >&2
exit 1
fi
jq -r '
if .type=="event_msg" and .payload.type=="user_message" then
"USER: " + (.payload.message // "")
elif .type=="event_msg" then
((.payload.type // "event") + ": " + (.payload.message // ""))
elif .type=="response_item" then
((.payload.role // "unknown") + ": " + ((.payload.content // []) | map(.text? // empty) | join("")))
else empty end
' "$f"
SH
chmod +x ~/bin/codexlog
使い方
# PATHに~/binを追加(.bashrcに書いておく)
export PATH="$HOME/bin:$PATH"
# 最新のログを表示
cd ~/.codex/sessions/2025/12/14
codexlog | less -R
# 特定のファイルを指定
codexlog rollout-2025-12-14T11-00-35-XXXXX.jsonl | less -R
端末側の設定(補助的対策)
TUIのスクロール上限は端末の設定に依存します。
tmuxの場合
~/.tmux.confに追加:
set -g history-limit 100000
Windows Terminalの場合
Settings → Profiles → 該当プロファイル → Scrollback lines を増やす(例:100000)
scriptコマンドで丸ごと録画
端末の出力をそのままファイルに保存する方法:
script -f codex.tui.log
codex
# 作業後
exit
これでcodex.tui.logにTUIの出力がすべて記録されます。
Codex CLIの便利なスラッシュコマンド
長い会話でコンテキストが溢れそうなときに使えるコマンド:
| コマンド | 説明 |
|---|---|
/compact | 現在の会話を要約してコンテキストを節約 |
/new | 同じCLI内で会話をリセット(セッションは維持) |
/status | 現在のセッション情報を表示 |
トラブルシューティング
jqでパースエラーが出る
jq: parse error: Invalid numeric literal at line 1, column 4
原因: head -n 1 rollout-*.jsonlで複数ファイルにマッチすると、headが見出し行(==> filename <==)を出力するため。
解決策: ファイルを1つだけ指定する
f=$(ls -1 rollout-*.jsonl | head -n 1)
head -n 1 "$f" | jq 'keys'
変数$fが古いファイルを指している
シェル変数はディレクトリを移動しても値が残ります。
解決策: 作業ディレクトリで変数を再設定する
cd ~/.codex/sessions/2025/12/14
f=$(ls -1 rollout-*.jsonl | head -n 1)
echo "FILE=$f"
または、フルパスで指定する:
f="$HOME/.codex/sessions/2025/12/14/rollout-2025-12-14T11-00-35-XXXXX.jsonl"
No such file or directory
確認方法:
pwd
echo "$f"
ls -l "$f"
現在のディレクトリと$fの値が一致しているか確認してください。
この方法が有効な理由
Codex CLIのログシステムは、UIが壊れても後から復元できるように設計されています:
- 会話をイベント列(JSONL)として全て記録
- 役割別(user/assistant/system)に分けて保存
- 日付+UUIDでファイルを整理
これは「見やすさ」より「壊れない記録」を優先した設計です。
jqでログを解析できるようになると:
- TUIの表示限界に縛られない
- 過去のセッションを自由に検索できる
- 会話をテキストとして保存・共有できる
- ツールが壊れても自力で復旧できる
まとめ
| やりたいこと | コマンド |
|---|---|
| ログの場所を確認 | ls ~/.codex/sessions/ |
| 最新のログを開く | f=$(ls -1t rollout-*.jsonl | head -n 1) |
| 構造を確認 | head -n 1 "$f" | jq 'keys' |
| ユーザー入力を抽出 | jq -r 'select(.type=="event_msg")...' "$f" |
| キーワード検索 | rg "キーワード" rollout-*.jsonl |
| 会話をテキスト化 | codexlog > convo.txt |
Google検索では見つからない情報ですが、知っておくと確実に役立ちます。
参考リンク
- Codex CLI Features – OpenAI Developers
- Codex Local Config – OpenAI Developers
- Codex Slash Commands – OpenAI Developers
- jq Manual
この記事が誰かの「見えない!」を解決できれば幸いです。
CodexのTUIで見えなくなった会話をログから復元する方法
CodexのTUI(Terminal User Interface)で長時間作業していると、過去の会話が見えなくなることがあります。これは会話が「消えた」わけではなく、TUIの表示限界で「見えなくなっている」だけです。
本記事では、ローカルに保存されているログ(JSONL形式)から会話を復元・検索する方法を解説します。
TUIとは
TUI(Terminal User Interface)は、ターミナル上で動作するユーザーインターフェースのことです。マウスで操作するGUIとは異なり、キーボード中心で操作します。Codexの画面もTUIの一種です。
ログの保存場所
Codex
~/.codex/sessions/YYYY/MM/DD/rollout-*.jsonl
Claude Code
~/.claude/projects/<project>/
どちらも考え方は同じで、「混ざっているログから必要な行だけ抜く」という発想で会話を復元できます。
ログを確認する準備
VSCodeで開く方法(推奨)
ログディレクトリは階層が深いため、コマンドで辿るよりVSCodeで.codexフォルダを開いて視覚的に確認するのが効率的です。
cd ~
ls -la .codex
ログは日付ごとに整理されています。日によってはファイルが複数あるため、まず「どれを読むか」を絞る必要があります。基本的には一番新しいrollout-*.jsonlから見ればOKです。
ログの構造を理解する
ログには主に2種類の重要なタイプがあります。
event_msg
ユーザーが入力した内容が記録されています。
jq -c 'select(.type=="event_msg") | .payload' "$f" | head -n 1 | jq .
出力例:
{
"type": "user_message",
"message": "こんにちは。\n最近、next.jsの脆弱性をつかれマルウェアに感染したんだ。",
"images": []
}
messageフィールドにユーザーが打った文章がそのまま入っています。
response_item
AIの応答やシステム情報が記録されています。
jq -c 'select(.type=="response_item") | .payload' "$f" | head -n 1 | jq .
出力例:
{
"type": "message",
"role": "user",
"content": [
{
"type": "input_text",
"text": "<environment_context>..."
}
]
}
role(user/assistant)とcontentの中に本文が入っています。環境情報も混ざるため、会話本文とは別枠で扱う必要があります。
構造の確認
jq -c 'select(.type=="response_item") | .payload' "$f" | head -n 1 | jq 'keys'
出力:
["content", "role", "type"]
type / role / contentがあれば、roleでユーザーとアシスタントを分けて、contentのtextだけ抜くことで会話を復元できます。

会話を抽出するjqコマンド
event_msgとresponse_itemから会話だけを抽出できます。抽出後はマウスホイールやキーボードの上下キー、PageUp/PageDownでスクロールできます。終了するときはアルファベットの「q」を押します。
特定のキーワードで検索する
rg(ripgrep)を使えば、特定のキーワードを含むログを素早く検索できます。
# nginx関連のログを検索
rg nginx "$f"
# プロキシ関連のログを検索
rg proxy "$f"
# ファイル名っぽいものを検索
rg -n "(/etc/nginx|nginx\.conf|sites-available|.conf|Dockerfile|next\.config|package\.json)" "$f"
# 編集・変更に関するログを検索
rg -n "edit|modify|change|update|patch|diff|ファイル|修正|変更" "$f"
ログで見えるもの・見えにくいもの
見える可能性が高いもの
- 「○○ファイルを編集した」「設定を変えた」などの説明文
- 実行したコマンド
- 作業ディレクトリ(cwd)や環境情報
見えにくい・保証できないもの
- パッチ全文(どの行をどう変えたかのdiff)
- 実際に書き換えられたファイルの中身そのもの
ログは「痕跡を拾う」用途には便利ですが、差分の真実を知るにはGitが最強です。
まとめ
codex resumeで再開はできるが、TUIでは過去の経緯が全部見えないことがある- ログを直接読むと、作業中に流れていた情報ややり取りが残っていて後から追える
- 会話はログから復元できるが、ファイルの変更内容を100%確実に残すなら
git diffが一番


