docs/guides/codex-unified-session-history-guide-ja.md
対象バージョン: CC Switch v3.16.x 以降。本記事は現在のコードをもとに整理しており、コマンドとパスはご自身で検証できます。例示には匿名化したデータを使用しており、実際のセッション内容や API Key は含まれていません。
「Codex セッション履歴を統一」は、CC Switch v3.16.x が Codex 向けに新しく追加したスイッチです。その場所は 設定 → 一般 → 「Codex アプリ拡張」グループ の中にあります(「Codex アプリ拡張」はこのグループの見出しで、スイッチ自体は「Codex セッション履歴を統一」という名前です)。オンにすると、公式サブスクリプション(ChatGPT ログイン / OpenAI API Key)のセッションが、CC Switch で管理するすべてのサードパーティプロバイダーのセッションと同じ履歴 / セッション再開リストに表示されます——もう、互いに見えない 2 つのリストに分断されることはありません。
Codex は「プロバイダーのラベル」(model_provider というフィールド)でセッションを分類しており、しかも セッション再開 / 履歴リストには、現在アクティブなプロバイダーと同じラベルのセッションしか表示しません。そのため、セッションは自然と 2 つの「引き出し」に分けられてしまいます。
openai ラベルに分類されます。custom ラベルに分類されます。2 つの引き出しは互いに見えません。公式とサードパーティを頻繁に切り替えている 場合、この分断に遭遇します——「さっき公式で話したセッションが、サードパーティに切り替えたら履歴リストから消えた」というように。実際にはなくなっておらず、別の引き出しに分けられただけです。この分断は、セッションが失われたと誤解させやすいうえに、すべてのセッションを 1 か所でまとめて振り返ったり再開したりするのにも不便です。
このスイッチは、まさにこの分断を解消するためのものです。公式サブスクリプションも custom ラベルで動作させることで、公式とサードパーティのセッションが同じリストに統合され、探すのも再開するのも 1 か所で済みます。
✅ 本記事全体を貫く重要な前提を、まず覚えておいてください: この機能(統一 / 移行 / 復元)は 常にセッション記録内のあの分類ラベル
model_provider1 つだけを書き換え、しかも毎回書き換える前に自動で元ファイルをバックアップします。あなたの会話を 1 文たりとも削除・消去・上書きすることはありません。ですので、本記事の後半で「あるセッションが見えなくなった」とあっても、そのほとんどは「別の引き出しに分けられた」だけであり、「データが消えた」わけではありません——本当に心配なときは、症状対照表 と 自分の目でファイルが残っていることを確認する を直接ご覧ください。
これを 2 つの引き出し + 自動バックアップ と考えてください。
openai の引き出しに、サードパーティのセッションは custom の引き出しにあり、互いに見えません。custom の引き出しを使うように させ、2 つの引き出しを 1 つの共有リストに統合します。完全な仕組み(何が注入されるのか、なぜ可逆なのか、移行 / 復元がどうやってデータ消失を防ぐのか)は、後述の コア・メンタルモデル と巻末の 応用原理付録 をご覧ください。
この機能を理解するには、引き出し と バックアップ の 2 つだけ覚えれば十分です。
Codex セッションを 1 つ開くたびに、Codex はセッションファイルの先頭に model_provider というラベルを記録し、「このセッションはどのプロバイダーで話したか」を示します。Codex の セッション再開 / 履歴リストは、現在アクティブなこのラベルで正確にフィルタリングされます——「今あなたが使っているプロバイダー」と同じラベルのセッションだけが表示されます。
openai です。custom を使います。そのためデフォルトでは、公式セッションとサードパーティセッションは生まれつき互いに見えません——2 つの異なる引き出しにあるからです。これは Codex 自身の設計 であり、CC Switch が何かをなくしたわけではありません。
デフォルト状態(統一スイッチをオンにしていない):
┌──────────────────────┐ ┌──────────────────────────────────┐
│ openai の引き出し │ │ custom の引き出し │
│ (公式セッション) │ │ (サードパーティのセッション) │
└──────────────────────┘ └──────────────────────────────────┘
▲ ▲
公式のときは サードパーティのときは
こちらだけ表示 こちらだけ表示
(2 つの引き出しは互いに見えない)
「Codex セッション履歴を統一」スイッチがすることは、公式サブスクリプションも custom ラベルで動作させ、2 つの引き出しを 1 つに統合することです。その結果、公式セッションとサードパーティセッションが同じセッション再開リストに表示されます。注意してほしいのは、認証は変わらない ということです——あなたの公式サブスクリプションは引き続き ChatGPT ログインを使い、引き続き公式バックエンドを経由します。変わるのはセッションの「分類ラベル」が openai から custom になることだけです。
統一スイッチをオンにした後:
┌────────────────────────────────────────────────┐
│ custom 共有引き出し │
│ 公式セッション + サードパーティのセッション │
│ (同じ履歴 / 再開リストに表示される) │
└────────────────────────────────────────────────┘
「引き出しの統合」では、一部の公式セッションのラベルを openai から custom に変更する必要があります(この操作を 移行 と呼び、これは 任意で、あなたが能動的にチェックを入れる必要があります)。そして どの書き換えの前にも、CC Switch はまず元ファイルをそのままコピー して、ここに保存します。
~/.cc-switch/backups/codex-official-history-unify-v1/<時間スタンプ>/
このバックアップが、後の「バックアップから正確に復元する」ための唯一の拠り所です。これによってプロセス全体が 可逆 になります——いつでもスイッチをオフにして、移行した公式セッションを正確に openai の引き出しへ戻せます。
この 2 つの言葉——引き出し(セッションは分類が変わるだけ)、バックアップ(変更前に必ずコピー)——を覚えておけば、以降の内容はすべて簡単に理解できます。
設定 → 一般 → Codex アプリ拡張
「Codex アプリ拡張」のセクションには 2 行のスイッチがあり、2 行目(青い履歴アイコン)が本ガイドの主役です。
Codex セッション履歴を統一
その下には説明文があります(逐語)。
オンにすると、公式サブスクリプションも共有の custom プロバイダー ID で動作し、公式とサードパーティのセッションが同じ履歴リストに表示されます。既存の公式セッションの移行も選択できます(移行前に自動バックアップ)。オフにする際はバックアップから復元できます。注意:プロバイダーをまたいで古いセッションを再開すると、encrypted_content の推論内容を相手のバックエンドが復号できず、再開に失敗する場合があります。
注意: この説明文には、すでに 3 つのことが予告されています——同じリストに表示される、移行を選べて自動バックアップされる、プロバイダーをまたいだ再開は「失敗する場合がある」。ここでの「再開に失敗する」は 続けられない、新しいターンを生成できない という意味であり、「記録が消える」ではありません。これこそ、この後で重点的に解きほぐす核心的な誤解です。
スイッチをオンに切り替えると、CC Switch は すぐには保存せず、まず確認ダイアログを表示します。ダイアログの文言は次のとおりです(逐語)。
タイトル: Codex セッション履歴を統一
本文:
オンにすると、公式サブスクリプションとサードパーティが同じセッション履歴リストを共有します。注意:プロバイダーをまたいで古いセッションを再開すると、encrypted_content を相手のバックエンドが復号できず失敗する場合があります。
既存の公式セッション履歴を共有リストへ移行することもできます(移行前に ~/.cc-switch/backups へ自動バックアップされ、オフにする際に復元を選択できます)。
チェックボックス: 既存の公式セッション履歴も移行する
確認ボタン: 理解しました、オンにする
キャンセルボタン: キャンセル
このチェックボックスはデフォルトでオフです。 これは重要な分岐点です。
| あなたの選択 | 効果 | この時点でデータはどこにあるか |
|---|---|---|
| チェックしない(デフォルト) | ラベルを切り替えるだけ。オンにした後に新規作成された公式セッションだけ が custom の共有引き出しに入る | あなたが オンにする前 の公式の古いセッションは、ラベルが openai のまま、その場で動かず、引き続き ~/.codex/sessions/ にある |
| チェックする | ラベルの切り替えに加えて、既存の公式の古いセッション も openai の引き出しから custom の引き出しへ移行する | 古いセッションは コピーしてバックアップ された後、ラベルが custom に書き換えられる。元データはバックアップで保護される |
「以前の公式セッションも統一リストに表示したい」なら、必ずこのチェックボックスを能動的にオンにしてください。 さもないと、下の対照表の「シナリオ A」に遭遇します——古いセッションが「消えた」ように見えますが、実際は元の引き出しに残っているだけです。
「キャンセル」を押すか、ダイアログの外側をクリックすると、スイッチはそのままオフ状態に戻り、何も起きません。 「理解しました、オンにする」を押すと、スイッチはオンとして保存され、CC Switch はバックグラウンドで設定をディスクに書き込みます(移行にチェックを入れていれば、移行を実行します)。
「既存の公式セッション履歴も移行する」にチェックを入れた場合、CC Switch はあなたの公式の古いセッションに対して、次の一連の流れを実行します。
公式(openai ラベル)の各セッションファイルについて:
① まず元ファイルをそのままバックアップディレクトリへコピー ← データの一次保険ができる
② 「一時ファイルに書く → まるごと置換」という原子的な方法で、
先頭行 session_meta 内の model_provider を
"openai" から "custom" へ変更するだけ ← 会話本文は 1 バイトも触らない
③ インデックス DB state_5.sqlite も同じトランザクション内でラベルを変更
~/.cc-switch/backups/codex-official-history-unify-v1/<時間スタンプ>/。移行のたびに、タイムスタンプ付きの「世代ディレクトリ」を生成し、その中に jsonl/(セッションのコピー)、state/(インデックス DB のコピー)、meta.json(この移行がどの Codex ディレクトリに属するかの記録)が含まれます。model_provider というフィールドの値だけ。あなたの会話内容、推論内容、すべての本文は そのまま保持 されます。移行が成功すると、これらの公式の古いセッションが統一リストに表示されます。この時点でのあなたのデータ: ① 元のコピーがバックアップディレクトリにある。② アクティブファイルは分類ラベルが変わっただけで、内容は無傷。
注意: 有効化と移行そのものは 成功通知を表示しません。移行は保存時にバックエンドが付随的に実行するもので、UI 上ではスイッチがオン状態になったのが見えるだけです。ですので「移行成功のダイアログが見えなかった」のは正常であり、失敗を意味しません。
無効化のとき、CC Switch はまず 一瞬かけて移行バックアップの有無を探索 し、それから確認ダイアログを表示します(そのため無効化のダイアログは少しだけ遅延しますが、これは正常です)。文言は次のとおりです(逐語)。
タイトル: セッション履歴の統一をオフにする
本文:
オフにすると、公式サブスクリプションとサードパーティはそれぞれ独立した履歴リストに戻ります。オン期間中に作成されたセッションは提供元を判別できないため、サードパーティの履歴に残り、公式サブスクリプションからは見えなくなります。
チェックボックス(条件付き表示): オンにした際に移行した公式セッションを公式履歴へ復元する(バックアップから正確に復元)
確認ボタン: オフにする
キャンセルボタン: キャンセル
ポイント: 本文が言っているのは「公式サブスクリプションからは 見えなくなる」——見えなくなる であり、削除される ではありません。オン期間中に新たに話したセッションは、引き続き
customの引き出しに完全な形で残っており、オフにした後で公式側から見えなくなるだけです。
この復元チェックボックスはデフォルトでオンです。 つまりデフォルトの動作は「オフにすると同時に、移行した公式セッションを公式履歴へ正確に復元する」です。チェックを保持したまま「オフにする」を押すだけで構いません。
チェックボックスが 表示されない 場合は、復元が必要なバックアップがないとシステムが判断したことを意味します(移行に一度もチェックを入れていない、またはバックアップを探索できない)——この場合、あなたの公式の古いセッションは一度も変更されていないので、スイッチをオフにすれば自然と openai の引き出しに戻ります。
チェックを保持して「オフにする」を押すと、CC Switch の復元フローは次のようになります。
① まず現在の状態を独立した復元バックアップディレクトリへもう一度コピー
~/.cc-switch/backups/codex-official-history-unify-restore-v1/<時間スタンプ>/
(復元自体もまずバックアップするので、復元でもデータは失われない)
② すべての移行バックアップ世代を走査し、「当初のラベルが openai」のセッション id を集めて「台帳」を作る
③ 【台帳に含まれ、かつ現在もまだ custom】のセッションだけ、ラベルを "openai" に戻す
③ のステップの 二重条件 に注意してください——台帳に含まれていること(当初確かに公式から移行されたものだと証明できる)に加えて、現在もまだ custom であること(あなたが手動で変更していないことを示す)。両方の条件を満たして初めて戻します。これにより、復元は正確であり、かつ誤って手を加えることもありません。
この時点でのあなたのデータ: 戻された公式セッションはラベルが openai に変わり、再び公式リストに表示されます。同時に、移行バックアップと復元バックアップの 2 つのコピーがどちらもディスク上に残っています。
「オフにする + 復元にチェック」というパスだけが結果通知を表示します。表示され得る通知(逐語)。
| 表示される通知 | 意味 |
|---|---|
| バックアップから公式セッション履歴を復元しました(セッションファイル {{files}} 件、インデックス {{rows}} 行) | 復元成功。{{files}} / {{rows}} の部分には実際の数字が表示される |
| 現在の Codex ディレクトリに復元可能な移行バックアップはありません | 復元できる内容がない(データが消えたわけではない。対照表シナリオ E を参照) |
| 統一セッション履歴が再度有効化されたため、復元をスキップしました | 復元のキュー待ち中にスイッチを再びオンにしたため、システムが復元を自発的に取りやめた(対照表シナリオ F を参照) |
| 公式セッション履歴の復元に失敗しました。もう一度お試しください | 復元の途中でエラー。もう一度試せばよく、データは破壊されていない |
| 保存に失敗しました。もう一度お試しください | オフにするステップの保存そのものが失敗。この場合 復元は決して起動されず、スイッチは元の位置に戻る |
気の利いた安全設計: 「スイッチをオフにする」ステップの保存が失敗した場合、CC Switch は 復元を決して実行しません。さもないと「スイッチはまだオン、しかしセッションは
openaiバケットに戻された」という矛盾状態が生じてしまいます。保存失敗時、スイッチは 自動で元の位置に戻る ので、「オフに見えるのに実は保存されていない」という偽の状態に取り残されることはありません。
以下の 6 つのシナリオは、ユーザーが最も「セッションが消えた」と誤解しやすいケースです。どれも真相は: データは無傷で、引き出しが変わったか一時的に見えないだけ。 まずこの表で症状から原因を特定し、その後で下の詳細説明を読んでください。
| シナリオ | あなたが見るもの | データの真相 | 一言での解決法 |
|---|---|---|---|
| A 移行にチェックなし | 公式の古いセッションが統一リストにない | すべて存在、openai ラベルのまま | 移行にチェックを入れて再度オンにする、またはスイッチをオフにする |
| B プロバイダーをまたいだ再開が失敗 | 続けられない / エラー | ファイルは無傷、暗号文がバックエンドをまたいで復号できないだけ | 元のプロバイダーで再開する。内容だけ見るなら jsonl を直接読む |
| C プロキシ接管 / 注入が拒否 | 移行も復元もされない | 移行が安全にスキップされ、ファイルは未変更 | 接管を終了 → 再起動して再試行。またはスイッチを直接オフにする |
| D 復元後、新セッションが公式に戻らない | オン期間中の新セッションが公式にない | custom の引き出しにある、設計上動かさない | サードパーティプロバイダーに切り替えれば見える |
| E 「復元可能なバックアップなし」と通知 | 復元が「失敗」 | 通常はそもそも移行していない、セッションは元の引き出しにある | スイッチをオフにすれば公式セッションが自動で再表示 |
| F 「スイッチが再度有効化、復元スキップ」と通知 | 復元が拒否 | データの矛盾を防止、何も変更していない | まずスイッチを完全にオフにしてから復元する |
現象: 統一スイッチをオンにしたが、有効化ダイアログの「既存の公式セッション履歴も移行する」にチェックを入れなかった(デフォルトでチェックなし)。オンにした後で見ると、以前の公式の古いセッションがすべてリストにないように見える。
真相: データは 100% すべて存在し、1 行も動いていません。スイッチは「オンにした後に新規作成された」公式セッションにのみ効きます。あなたが オンにする前 の公式の古いセッションはラベルが openai のままで、そっくりそのまま ~/.codex/sessions/ に横たわっています。今あなたがアクティブにしているのは custom の引き出しなので、openai の引き出しに残った古いセッションが見えないのは当然です——これが「消えたように見える」理由のすべてです。
どうするか(いずれか):
custom の引き出しへ移せば、すぐに統一リストに表示されます(書き換え前に自動バックアップ)。openai の引き出しで動作し、古いセッションがその場で再表示されます。現象: 統一した後、リストに「別のプロバイダー」で話した古いセッションが見える。今のプロバイダーに切り替えて「再開」を押すと、エラーになったり繋がらなかったりする。
真相: セッションファイルは完全に無傷で、失われたのはデータではなく「バックエンドをまたいだ復号能力」です。Codex セッションには暗号化された推論内容 encrypted_content が保存されており、この暗号文は、それを生成したバックエンドだけが復号できます。B プロバイダーで A プロバイダーが生成したセッションを再開しようとすると、B は A の暗号文を解けない → 再開失敗。これは 上流の Codex の設計上の制約(by design) であり、CC Switch がファイルに手を加えたかどうかとは無関係です。セッション内の文字内容はいつでも読めます。
これは本記事全体で 唯一「本当に問題が起きたように見える」実在の例外 です——ただし注意してください: これは 再開できない(新しいターンを生成できない) だけであり、元ファイルは依然として完全に存在し、会話の文字はいつでも読めます。
どうするか:
.jsonl ファイルを直接読んでください(巻末にコマンドあり)。現象: オンにして移行にチェックを入れたのに、公式の古いセッションは統一リストに入らず、スイッチをオフにして復元しようとしても「復元できるものがない」と通知される(または無効化ダイアログに復元チェックボックスがそもそも現れない。シナリオ E を参照)。あなたは、移行の過程でセッションをなくしたのではと疑います。
真相: 移行はそもそも 実行されていない ので、なくすことも不可能です——あなたのセッションは 1 文字も変更されていません。CC Switch には移行前に安全ゲートがあります: Codex の live 設定(~/.codex/config.toml)が、この時点で 本当に 共有の custom 引き出しへルーティングされているかを確認し、本当にルーティングされている場合だけ移行します。以下の 2 つのケースでは「まだ統一されていない」と判定され(内部の理由コード live_not_unified)、移行を自発的にスキップし、あなたのスイッチと移行の意思は保持し、条件が満たされてから移行します。
config.toml にすでに手動指定の model_provider があるか、形態の異なる [model_providers.custom] テーブルが既に存在する(サードパーティのアドレスが付いている可能性がある)。公式トラフィックを誤ってサードパーティバックエンドへルーティングするのを避けるため、CC Switch は注入も移行もしないことを選びます。移行のスキップ = どのセッションファイルにも触れない。移行していない=動かしていない、消えようがない。 これは「安全な先送り」であり、「失敗してデータが消えた」ではありません。
どうするか:
~/.codex/config.toml を確認: 手動で書いた競合するルーティングがあれば、競合を整理してからスイッチをオンにします。openai の引き出しで正常に表示され、まったく無傷です。現象: 統一をオンにしている間、公式でさらにいくつかの新セッションを話した。後でスイッチをオフにし、復元にチェックを入れた。復元が終わると、その数本の新セッションが公式の引き出しに戻っていない。
真相: これは 意図的な 設計で、新セッションはちゃんと custom の引き出しにあり、見えるし続けられます。復元の拠り所は「移行時のバックアップ台帳」です——当初 openai の引き出しから移行されてきたセッションだけ がバックアップに記録されており、正確に openai へ戻されます。あなたが オン期間中に新規作成した セッションはどのバックアップ台帳にもありません。しかも統一後は公式もサードパーティも custom ラベルを使うので、CC Switch はこの新セッションが公式で話したものかサードパーティで話したものか判別できません。サードパーティのセッションを公式履歴に誤って押し込まないため、プロダクトの決定として、これらの新セッションは一律に custom(サードパーティ)の履歴に残し、決して自動で動かしません。無効化ダイアログの文言もこれを明示しています——「オン期間中に作成されたセッションは提供元を判別できないため、サードパーティの履歴に残ります」。
どうするか:
custom の引き出し)に切り替えれば、履歴リストでこれらのセッションが見えます。.jsonl を直接読み、再開したいならシナリオ B のルール(それを生成した元のバックエンドに戻る)に従ってください。.jsonl の 1 行目 session_meta 内の model_provider を custom から openai に手動で戻せます(上級操作です。変更前に必ずコピーを取ってください)。現象: スイッチをオフにするときに復元にチェックを入れたら、「現在の Codex ディレクトリに復元可能な移行バックアップはありません」と通知が出た。あなたは慌てます: 復元すら失敗した、データは完全に消えたのでは?
真相: 「復元できるものがない」≠「データが消えた」。むしろ逆で、通常は そもそも復元すべき移行が存在しない からです。よくある原因:
openai の引き出しにあり、スイッチをオフにすれば直接再表示されます(シナリオ A と同じ)。(この場合、無効化ダイアログは復元チェックボックスを そもそも表示しない こともあります——システムがバックアップを一切探索できないためです。)openai に戻っており、もう一度押しても「まだ custom の対象がない」のは当然です——これは 冪等保護であり、失敗ではありません。この 3 つのケースでは、どのセッションも削除されていません。
どうするか: 巻末のコマンドで ~/.codex/sessions/ 内のセッションファイル総数を数え、ファイルがすべて残っていることを確認してください。次に ~/.cc-switch/backups/ に codex-official-history-unify-v1 ディレクトリがあるかを見てください——もしこのディレクトリすらなければ、あなたは一度も移行を起動しておらず、セッションはずっと元の引き出しにある、ということです。
現象: スイッチをオフにする → 復元にチェック → 手が速くて、すぐにスイッチを再びオンにした。すると「統一セッション履歴が再度有効化されたため、復元をスキップしました」と通知が出た。
真相: これはデータを「矛盾」状態にしてしまうのを防ぐ防護であり、セッションは同じく消えていません。復元の動作は「セッションラベルを custom から openai へ戻す」ことですが、この時点でスイッチが再びオンになっていると、live 設定は custom へルーティングしています——一方で履歴を openai へ戻し、一方で新セッションを custom に落とせば、セッションが人為的に 2 つに引き裂かれてしまいます。そのため CC Switch は「スイッチが再びオンになった」のを検知すると、この復元を自発的に取りやめ、何も変更しません。セッションは現状を維持し、削除も破壊もありません。
どうするか: 本当に復元したいなら、まずスイッチを安定してオフにし(すぐにオンにし直さない)、それから「オフにする + 復元にチェック」を実行してください。統一を保ちたいなら、復元せず、セッションを custom の共有引き出しに残して通常どおり使ってください。
大原則: CC Switch の統一 / 移行 / 復元は、全工程でセッションの 1 つのラベルフィールドだけを変更し、しかも毎回書き換える前に自動でバックアップします。あなたの会話を削除することはありません。見えない ≠ 消えた——別の引き出しを見るか、下のコマンドで自分の目で確かめてください。
文字をいくら重ねるより、自分の目で見るのが一番です。以下に 実際のパス(CC Switch のソースコードから取得)と、異なる OS でセッションファイル・バックアップディレクトリを見る方法を示します。全工程は読み取りのみで変更なし。ぜひ一度ご自身で試してみてください。
Cmd + Shift + G を押して ~/.codex/sessions を貼り付けて Enter すれば、たくさんの .jsonl セッションファイルとその更新時刻が見えます。バックアップディレクトリは ~/.cc-switch/backups を貼り付けます。%USERPROFILE%\.codex\sessions を貼り付けて Enter すれば、セッションフォルダとその中の .jsonl が見えます。バックアップディレクトリは %USERPROFILE%\.cc-switch\backups を貼り付けます。ここで一連の .jsonl ファイルが見えれば、それがセッションデータが無傷でディスク上にある証拠です。 ファイル数や更新時刻は、どんな文章よりも直感的です。
| 内容 | 実際のパス | 説明 |
|---|---|---|
| セッション本文(コア) | ~/.codex/sessions/(日付別サブディレクトリを含む、再帰的) | セッション 1 つにつき 1 つの .jsonl テキストファイル。これがあなたの会話内容 |
| アーカイブ済みセッション | ~/.codex/archived_sessions/ | 同じく .jsonl |
| セッションインデックス DB | ~/.codex/state_5.sqlite | threads テーブルの model_provider 列が「引き出しラベル」。これこそ、セッション再開リストが実際に読み取る分類のソース |
| 移行バックアップ(移行をオンにすると自動生成) | ~/.cc-switch/backups/codex-official-history-unify-v1/<時間スタンプ>/ | jsonl/、state/、meta.json を含む |
| 復元バックアップ(復元を押すと自動生成) | ~/.cc-switch/backups/codex-official-history-unify-restore-v1/<時間スタンプ>/ | 復元前の安全なコピー |
注意: CC Switch で Codex ディレクトリを変更した場合や、
config.tomlでsqlite_homeを設定している場合は、上記の~/.codexをあなたの実際のディレクトリに置き換えてください。以下の~= あなたのユーザーホームディレクトリ。
1. セッションファイル総数を数える(これこそ「消えていない」確固たる証拠)
# セッションファイルの総数を数える —— この数が想定どおりなら、データはすべて残っている
find ~/.codex/sessions ~/.codex/archived_sessions -name '*.jsonl' 2>/dev/null | wc -l
# 最近更新されたセッションファイル上位 10 件を見る
find ~/.codex/sessions -name '*.jsonl' 2>/dev/null -print0 \
| xargs -0 ls -lt 2>/dev/null | head -10
2. (補助)各「引き出し」にそれぞれ何個のセッションがあるか見る
# 公式の引き出し(openai)のセッションファイル数
grep -rlE '"model_provider"[[:space:]]*:[[:space:]]*"openai"' ~/.codex/sessions 2>/dev/null | wc -l
# 統一の引き出し(custom)のセッションファイル数
grep -rlE '"model_provider"[[:space:]]*:[[:space:]]*"custom"' ~/.codex/sessions 2>/dev/null | wc -l
# 各ラベルの分布をひと目で確認
grep -rhoE '"model_provider"[[:space:]]*:[[:space:]]*"[^"]*"' ~/.codex/sessions 2>/dev/null | sort | uniq -c
重要なヒント、このステップに驚かないでください: 初期バージョンの Codex は
.jsonlにmodel_providerフィールドを書き込みません。これらの古い公式セッションは上記の grep では 数えられません が、インデックス DBstate_5.sqliteでは依然としてopenaiに分類されており、セッション再開リストではちゃんと見えます。ですので 「セッションが消えていない」かの判断はステップ 1 のファイル総数を基準にしてください——バケット別 grep は分類を理解する補助に過ぎず、数えた結果がファイル総数より少ないのは まったく正常 であり、決して「ひとまとまり消えた」ことを意味しません。
3. (応用)インデックス DB state_5.sqlite を見る——セッション再開リストが実際に読む分類
# sqlite3 がインストール済みであること;未インストールならスキップ可
sqlite3 ~/.codex/state_5.sqlite \
"SELECT COALESCE(model_provider,'<空>'), COUNT(*) FROM threads GROUP BY 1;"
この
threadsテーブルこそ、Codex のセッション再開リストが実際に読み取る分類のソースであり、openaiの行数 ≈ あなたの公式の引き出しで見えるセッション数です。ステップ 2 の jsonl grep とは数が合わないことがあります——その理由は、上述の「古いセッションは jsonl フィールドを書き込まないが、インデックス DB では依然として openai」だからです。両者が合わないのは異常ではありません。
4. あるセッションの内容を直接読む(会話の文字が残っていることを確認)
# <ファイル名> を、上の ls で表示された .jsonl のパスに置き換える
python3 -m json.tool < "<ファイル名>.jsonl" 2>/dev/null | head -50
# またはエディタで直接開いて見る(プレーンテキスト)
open -e "<ファイル名>.jsonl" # macOS
5. CC Switch のバックアップディレクトリを見る(移行 / 復元の前に必ずコピーを残した証拠)
ls -la ~/.cc-switch/backups/codex-official-history-unify-v1/ 2>/dev/null
ls -la ~/.cc-switch/backups/codex-official-history-unify-restore-v1/ 2>/dev/null
セッションディレクトリは通常 C:\Users\<あなたのユーザー名>\.codex\ にあり、バックアップは C:\Users\<あなたのユーザー名>\.cc-switch\backups\ にあります。
# 1. セッションファイルの総数(「消えていない」ことの動かぬ証拠)
(Get-ChildItem "$env:USERPROFILE\.codex\sessions","$env:USERPROFILE\.codex\archived_sessions" -Recurse -Filter *.jsonl -ErrorAction SilentlyContinue).Count
# 2. 最近更新されたセッション上位 10 件
Get-ChildItem "$env:USERPROFILE\.codex\sessions" -Recurse -Filter *.jsonl |
Sort-Object LastWriteTime -Descending | Select-Object -First 10 FullName,LastWriteTime
# 3. (補助)公式(openai) / 統一(custom) の引き出しにそれぞれ何件のセッションファイルがあるか
(Get-ChildItem "$env:USERPROFILE\.codex\sessions" -Recurse -Filter *.jsonl |
Select-String -Pattern 'model_provider"\s*:\s*"openai"' -List).Count
(Get-ChildItem "$env:USERPROFILE\.codex\sessions" -Recurse -Filter *.jsonl |
Select-String -Pattern 'model_provider"\s*:\s*"custom"' -List).Count
# 4. バックアップディレクトリを見る
Get-ChildItem "$env:USERPROFILE\.cc-switch\backups\codex-official-history-unify-v1" -ErrorAction SilentlyContinue
Get-ChildItem "$env:USERPROFILE\.cc-switch\backups\codex-official-history-unify-restore-v1" -ErrorAction SilentlyContinue
同じく注意: ステップ 3 の grep の数がファイル総数より 少なくなる のは正常です(古いセッションはこのフィールドを書き込まないため)。「セッションが消えていない」の判断は、ステップ 1 の ファイル総数 を基準にしてください。
Codex のセッション再開 / 履歴リストは、現在アクティブな model_provider id で 厳密な文字列フィルタリング を行います。セッションファイル .jsonl の 1 行目 は type:"session_meta" のレコードで、その payload.model_provider がそのセッションの属する引き出しです(grep -rl はファイル内にそのラベルが 1 回でも出現すればそのファイルをカウントするので、行ごとに解析する必要はありません。旧バージョンでこのフィールドを書き込んでいないセッションは数えられません)。セッション再開リストを実際に駆動するのはインデックス DB state_5.sqlite の threads.model_provider 列です。公式サブスクリプションは config.toml に明示的な model_provider がないとき、内蔵のデフォルト id openai に入ります。CC Switch のすべてのサードパーティプロバイダーは一律に custom を使います。
オンにすると、CC Switch は公式 live config.toml に次の内容を注入します。
model_provider = "custom"
[model_providers.custom]
name = "OpenAI"
requires_openai_auth = true
supports_websockets = true
wire_api = "responses"
各フィールドには役割があります。requires_openai_auth = true は認証を引き続き auth.json 内の ChatGPT ログインで行わせ、base_url 未指定時は公式 Codex バックエンドへフォールバックさせます。name = "OpenAI" は Codex の公式機能ゲート(web search、リモート圧縮など)を引き続きヒットさせます。supports_websockets = true は custom エントリでデフォルトに失われる能力を補います。wire_api = "responses" は公式の responses プロトコルを使います。正味の効果は: 認証は変わらず、バケット名が変わるだけ。
重要な不変条件: この注入は live config.toml にのみ存在でき、決してデータベースの保存設定には書き込まれません。 公式プロバイダーから切り替えて離れ、live をデータベースへ書き戻すとき、CC Switch はこの注入を正確に剥離します(形態が注入物と完全に一致するときだけ剥離し、サードパーティがカスタムした custom テーブルはそのまま保持します)。だからこそ「スイッチをオフにする + 一度切り替える」だけで live を完全に復元でき、データベースには常にあなた本来のクリーンな公式設定が保たれます——これがスイッチ全体の可逆性の礎です。
config.toml に明示的な model_provider がすでにある → ユーザーのルーティングを上書きしない。[model_providers.custom] テーブルがすでに存在する(サードパーティの base_url が付いている可能性がある)→ 注入を拒否、さもないと ChatGPT OAuth トラフィックを誤ったバックエンドへルーティングしてしまう。注入を拒否したとき live は統一されず、移行ゲート(live の model_provider が trim 後に custom と等しいかを確認)が live_not_unified と判定 → 移行をスキップし、意思を保持し、次回起動の再試行時に行います。これは「安全な先送り」であり、「失敗してデータが消えた」ではありません。
openai へ復元可能。custom に残す)。4 層の設計が共同で保証します: 正常・異常のあらゆるパス において、元のセッションデータが本当に削除されることはありません。
model_provider の値を openai と custom の間で切り替えるだけで、会話内容、response_item、encrypted_content はすべてそのまま保持します。codex-official-history-unify-v1/ に、復元バックアップは独立した codex-official-history-unify-restore-v1/ にあり、台帳を純粋に保つため両者は分けられています。UPDATE を経由し、全工程でセッションやインデックスを削除する操作は一切ありません。ファイルはいかなる時点でも完全です。live_not_unified)は移行しないことを選びます。一つのプロセスロックが移行と復元を直列化し、「起動時の再試行 / 保存後のバックグラウンドタスク / 無効化時の復元」が同じ一群のファイルを並行して双方向に書き換えるのを防ぎます。完了マークは Codex ディレクトリに紐づけて条件付きで書き込み、移行漏れを防ぎます。復元は「台帳にある + 現在もまだ custom」の二重条件を使い、誤変更を防ぎます。復元スキャンはすべてのバックアップ世代の和集合を取り、何度もスイッチを切り替えた後でも初期に移行したセッションを復元できます。重複した復元は nothing_to_restore を返しますが、これは冪等保護であり失敗ではありません。セッション内の推論暗号文は、それを生成したバックエンドだけが復号でき、上流の Codex は by design でバックエンドをまたいだ復号をサポートしません。これが「再開失敗」の根本原因であり、ファイルの完全性とは無関係です——セッション .jsonl は完全にディスク上に横たわり、encrypted_content も無傷です。元のプロバイダーに戻して再開するか、新規セッションを始めれば、どちらも正常です。
最後に一言: あなたが見た「セッションが消えた / 再開失敗」は、本質的には セッションが別の履歴リスト(引き出し)に移されたか、相手のバックエンドが古い推論内容を復号できない ことであり、ファイルは常にそっくりそのまま ~/.codex/sessions/(および state_5.sqlite)に横たわっています。スイッチをオフにするとき「バックアップから復元する」にチェックを入れれば、移行した公式セッションを正確に公式リストへ戻せます。たとえ復元しなくても、元の .jsonl ファイルと ~/.cc-switch/backups/codex-official-history-unify-*/ 配下のバックアップコピーはどちらも残っています——データが本当に失われることは決してありません。