mcpField
C
codex-session-recovery

codex-session-recovery

github.com/huajiexiewenfengエージェントワークフロー880 回インストール22 週間前に更新
リポジトリ

codex-session-recovery について

codex-session-recoveryは、ローカルに残っているのにCodex Desktopの画面に表示されないセッションを扱う復旧スキルです。セッション索引やプロジェクトの対応付け、作業ディレクトリの完全一致を調べ、バックアップを伴う修復と確認を案内します。

主な機能

  1. 01dry-runモードでの復旧チェック
  2. 02欠落したセッション索引レコードの検出
  3. 03プロジェクトとサイドバーの対応付け確認
  4. 04バックアップ後のセッションメタデータ修復
  5. 05復旧結果と作業ディレクトリ一致の検証
  6. 06非表示スレッドと最近のスレッド数制限への対応

活用シーン

  1. 01画面にないCodexセッションの復元
  2. 02プロジェクトルートとセッションパスの不一致診断
  3. 03バックアップ後のサイドバー割り当て修復
  4. 04復元後もスレッドが表示されない原因の調査

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/huajiexiewenfeng/codex-session-recovery --skill codex-session-recovery

インストール後、Claude Code で/codex-session-recoveryを入力して読み込まれたか確認します。

同梱ファイル

SKILL.md と一緒にインストールされる参考資料やスクリプト。

scripts/
recover_codex_global_state.py
reparent_codex_sessions.py
restore_codex_project_sessions.py
run_recovery_after_codex_exit.ps1
surface_codex_sidebar_threads.py

詳細

Codex セッションの復元

ディスク上には残っているものの、UI から見えなくなったローカルの Codex Desktop セッションを復元するには、このスキルを使用します。

よくある障害の状況は次のとおりです。

  • sessions/**/*.jsonl と state_5.sqlite にはスレッドが残っています。
  • session_index.jsonl には一部のレコードがない場合があります。
  • .codex-global-state.json には、project-order、thread-workspace-root-hints、thread-project-assignments、sidebar-project-thread-orders など、プロジェクトやサイドバーへの割り当てキーがない場合があります。
  • Codex Desktop の実行中に手動で編集すると、メモリ内の状態で上書きされることがあります。

安全に関するルール

  • セッションファイルは削除しないでください。
  • 書き込みの前に、必ずタイムスタンプ付きのバックアップを作成してください。
  • session_meta.payload.cwd に基づくプロジェクトルートの完全一致を優先してください。
  • ユーザーが明示的により広い範囲での一致を求めない限り、パスへの全文検索での言及をプロジェクトへの所属と見なさないでください。
  • Codex Desktop が実行中の場合、実行中のアプリへの書き込みをユーザーが明示的に承認しない限り、グローバル状態を書き込まないでください。Electron によってファイルが再び上書きされる可能性があることを説明してください。
  • missing_* の件数が 0 になっても復元したスレッドが UI に表示されない場合は、グローバル状態のキーを推測して追加し続けないでください。表示されているプロジェクトルートがセッションの cwd と異なっていないか確認してください。
  • thread/list.cwd は完全一致のフィルターであり、前方一致のフィルターではありません。cwd が D:\repo\subdir のスレッドは、ルートが D:\repo の UI プロジェクトに表示されない場合があります。
  • Codex Desktop 26.527 では、プロジェクトのサイドバーは thread/list limit: 50 から始まる最近のスレッドのキャッシュを使って構築されます。新しい app-server の thread/list --cwd <root> で古いセッションが返されるのに、UI プロジェクトに「No recent chats」と表示される場合、セッションがグローバルな最近のスレッドの最初のページより後にあるだけかもしれません。SQLite、JSONL ロールアウト、グローバル状態をバックアップしてから、surface_codex_sidebar_threads.py を使用してください。SQLite のタイムスタンプだけを更新しても永続しません。再起動時の app-server の読み取り修復によって、JSONL から再構築される可能性があるためです。
  • Windows の拡張長パスは、別個の完全一致リスクとして扱ってください。\\?\D:\repo\project と D:\repo\project は同じファイルシステムパスに正規化されますが、Codex UI の cwd フィルターでは同じ文字列として扱われないことがあります。メタデータの修復後も履歴が表示されない場合は、SQLite の threads.cwd に \\?\ のプレフィックスが付いているか確認し、reparent_codex_sessions.py --old-root <root> --new-root <root> --write で正規化してください。
  • 対象ディレクトリが Git のサブディレクトリの場合は、git rev-parse --show-toplevel と session_meta.payload.cwd を比較してください。Codex がサイドバーを Git ルート単位でグループ化する場合は、SQLite と JSONL ファイルをバックアップしてから、一致するセッションを Git ルートに再割り当てしてください。

ワークフロー

  1. CODEX_HOME を解決します。
    • 実在するディレクトリを指している場合は、$env:CODEX_HOME を優先します。
    • それ以外の場合は、%USERPROFILE%\.codex を使用します。
  2. 対象プロジェクトのルートを解決します。
    • ユーザーが指定したパスを使用します。
    • 省略されていて、現在のワークスペースが対象である場合は、現在の作業ディレクトリを使用します。
  3. まず、同梱スクリプトをドライランモードで実行します。
  4. 次のレポート項目を確認します。
    • exact_project_sessions
    • missing_from_session_index
    • missing_global_hints
    • sqlite_exact_ui_cwd_threads
    • sqlite_non_exact_ui_cwd_threads
    • cwd_exact_match_risk
    • codex_processes_running
    • can_write_global_state_safely
  5. Codex が実行中で、グローバル状態の修復が必要な場合:
    • 対応を求める前に、手順を簡潔にまとめてユーザーに状況を伝えます。
    • 「Codex を完全に終了してください」とだけ伝えてはいけません。Electron、トレイ、ヘルパーの codex.exe プロセスを閉じる方法を知らないユーザーも多くいます。
    • Codex を自動的に終了/再起動して復旧を続行するか、ユーザーに確認します。
    • ユーザーが同意した場合は、現在の Codex ウィンドウが終了した後も復旧を続行できるよう、外部ヘルパープロセスを使用します。
    • ユーザーが同意しない場合は、Codex Desktop を完全に終了してから、外部ターミナルでスクリプトを実行するよう依頼します。
    • 上書きのリスクを許容する場合は、--allow-running-codex を指定して実行します。ただし、SQLite がロックされたままになる可能性があり、Electron がグローバル状態を上書きする可能性があることを説明します。
  6. 書き込みモードを実行します。Windows では、メインスクリプトでも同一ディレクトリ内の \\?\D:\... の cwd 値を正確な表示ルートの文字列に書き換えられるよう、--normalize-windows-extended-paths を優先します。
  7. ドライランモードを再実行して、次の項目を確認します。
    • missing_from_session_index: 0
    • missing_global_hints: 0
    • missing_project_assignments: 0
    • missing_sidebar_order: 0
    • cwd_exact_match_risk: false
  8. UI にスレッドが表示されない場合:
    • app-server のスキーマ、または生成された ThreadListParams の JSON スキーマを調べます。
    • cwd は完全一致であることに注意します。
    • state_5.sqlite の threads.cwd を確認します。行に \\?\D:\... が使われている場合は、同じルートへの再親設定を実行して、表示ルートの文字列に書き換えます。
    • git -C <project-root> rev-parse --show-toplevel を実行します。
    • Git ルートがプロジェクトルートと異なる場合は、表示ルートを修正するか、セッションを Git ルートに再親設定します。
    • cwd が完全一致していて、新しい app-server が非表示のスレッドを返す場合は、グローバルな thread/list の順位を調べます。Codex Desktop が、プロジェクトのサイドバーに最新のスレッドを最初の 50 件だけ読み込んでいる可能性があります。
    • その場合は、surface_codex_sidebar_threads.py を実行し、復元したプロジェクトスレッドから上限付きのラウンドロビン方式で一部を最近使用したスレッドのキャッシュに表示します。この処理では、バックアップとレポートを作成し、JSONL の task_complete.completed_at、SQLite の updated_at/updated_at_ms、およびグローバルなプロジェクトマッピングを更新します。
  9. 復旧に再起動が必要な場合は、次に何が起きるかをユーザーに伝え、自動的に実行するか確認します。同意した場合は、再起動ヘルパーを実行します。同意しない場合は、Codex Desktop を再度開き、プロジェクト一覧を確認するよう伝えます。
  10. 非表示の外部ヘルパーを起動した後は、実際に引き継ぎが行われたことを確認してから、実行中だと伝えます。
  • プロジェクトルートの下に想定されるログファイルが存在するか確認します。または、C:\tmp のパスを指定して -LogPath を渡します。
  • ログが見つからない場合は、実行中の powershell.exe ヘルパープロセスが存在するか確認します。
  • ログが現れず、Codex/codex プロセスが残っている場合は、ヘルパーの起動に失敗したか、ログ出力前に失敗したものとして扱います。復旧が進行中だとユーザーに伝えてはいけません。
  • プロセスの調査や停止時に Access is denied が報告された場合、Codex プロセスの Path が空または null の場合、あるいは -StopCodexFirst の実行後も WindowsApps の Codex プロセスが残っている場合は、UAC ヘルパーの手順に切り替えます。

ユーザー向けプロンプトのパターン

dry-run で復旧可能なセッションが見つかり、Codex が実行中の場合は、ユーザーへの案内を簡潔かつ実務的にしてください。次の形式を推奨します。

1. 已按 `codex-session-recovery` 流程处理到安全恢复阶段。
2. Dry-run 结果:当前项目 `<project-root>` 找到 `<N>` 条历史 session。
3. `session_index` <缺失情况>,全局侧边栏映射 <缺失情况>,SQLite 的 `cwd` <是否存在 `\\?\` 精确匹配风险>。
4. 日志在这里:`<log-path>`。

现在需要重启 Codex Desktop 才能继续恢复。是否需要我帮你自动关闭并重启 Codex?

ユーザーが「はい」と答えた場合は、Codex のプロセスをすべて手動で探すよう求めず、外部ヘルパーを使ってください。ユーザーが「いいえ」と答えた場合は、Codex を終了した後に実行できる正確な PowerShell コマンドを提示してください。

自動終了/再起動の案内

次のすべてに該当する場合は、自動終了/再起動を使用してください。

  • Codex が実行中で、can_write_global_state_safely が false、または SQLite が disk I/O error を報告している。
  • ユーザーが、エージェントによる Codex の終了/再起動を明示的に許可している。
  • 現在の Codex ウィンドウの終了後も動作する外部 PowerShell プロセスを起動できる。

Windows に関する重要な注意事項:

  • 自身のプロセスツリーを強制終了するヘルパーは起動しないでください。Codex によって復旧用 PowerShell が起動された場合、taskkill を使うときは /T を避けてください。/T を使うと、メタデータを書き込む前にヘルパーが終了することがあります。
  • Codex の終了を待ってから検証を実行するため、十分であれば同梱の run_recovery_after_codex_exit.ps1 を優先してください。
  • 一時的なヘルパーを作成する必要がある場合は、.ps1 ソース内に ASCII 以外の文字を含むプロジェクトパスをハードコードしないでください。$PSScriptRoot、(Get-Location).Path を使うか、パスを引数として渡してください。そうすることで、Windows PowerShell 5 のエンコーディングによって日本語のパスが文字化けするのを防げます。
  • Start-Process が Path/PATH 環境変数の重複キーで失敗する場合は、外部プロセスを起動する前に、プロセスレベルの重複した PATH 変数を削除してください。
  • Codex の停止が Access is denied で失敗した場合は、Start-Process -Verb RunAs を使い、UAC プロンプトを承認するようユーザーに伝えてください。
  • 非表示のヘルパーがすぐに戻り、ログを作成せず、Codex のプロセスがすべて実行中のままの場合は、同じ非表示コマンドを再試行しないでください。明示的に -LogPath を C:\tmp に指定して再実行してください。ログが見つからない、またはアクセス拒否と記録されている場合は、UAC ヘルパーを使ってください。
  • 明示的な C:\tmp のログパスを指定して起動した非表示ヘルパーが、2〜3 秒後もログを作成せず、同じ Codex/codex プロセスが残っている場合は、「復旧はまだ実行中」ではなく「ヘルパーが処理を引き継がなかった」と判断してください。すぐに UAC ヘルパーを使い、ログが見つからないことを理由として報告してください。
  • 自動復旧後に dry-run を再実行し、復旧完了とする前に missing_*: 0 および cwd_exact_match_risk: false を必須条件として確認してください。

グローバル状態の修復に成功した後も UI が空のまま

missing_from_session_index、missing_global_hints、missing_project_assignments、missing_sidebar_order がすべてゼロでも、左サイドバーに履歴が表示されない場合は、まだ復旧に成功したと判断しないでください。次の項目を順番に確認してください。

  1. Codex が最新の復旧スクリプトを実際に実行したことを確認します。ログに想定されるステップ名が含まれているはずです。編集中に開始した待機中のスクリプトは、古いスクリプトの内容を実行し続けます。
  2. 書き込み前に、Codex または codex のプロセスがまだ動作していないことを確認します。実行中の Electron がメモリ上の状態を上書きする可能性があります。
  3. メインスクリプトの cwd の完全一致フィールドを確認します。
sqlite_exact_ui_cwd_threads
sqlite_non_exact_ui_cwd_threads
sqlite_extended_path_threads
cwd_exact_match_risk
recommended_cwd_normalization

cwd_exact_match_risk が true の場合、グローバル状態の missing_* の件数がすべてゼロでも、Codex UI でスレッドが非表示のままになることがあります。

  1. SQLite の Windows 拡張長パスの不一致を確認します。
$py = "C:\Users\admin\.cache\codex-runtimes\codex-primary-runtime\dependencies\python\python.exe"
& $py -c "import sqlite3; con=sqlite3.connect(r'C:\Users\admin\.codex\state_5.sqlite'); [print(row) for row in con.execute(\"select id,cwd,title from threads where cwd like '%smartghub%' order by created_at desc\")]"

threads.cwd が \\?\ で始まっている一方、UI のプロジェクトルートが通常のパスである場合は、メインの復元スクリプトで同じプロジェクトルートを正規化します。

$py = "C:\Users\admin\.cache\codex-runtimes\codex-primary-runtime\dependencies\python\python.exe"
$skill = "C:\Users\admin\.codex\skills\codex-session-recovery"
$root = (Get-Location).Path
& $py "$skill\scripts\restore_codex_project_sessions.py" --project-root $root --write --normalize-windows-extended-paths
  1. app-server の仕様を確認します。
$env:CODEX_HOME = "C:\Users\admin\.codex"
codex app-server generate-json-schema --out .\app-server-schema
Get-Content .\app-server-schema\v2\ThreadListParams.json

cwd フィルターには、セッションの cwd がパスのいずれかと完全に一致するスレッドのみを返すと記載されています。

  1. プロジェクトルートと Git ルートを比較します。
git -C "D:\workspace\drone\cloudsmartgo\smart-go-web" rev-parse --show-toplevel

このマシンでは、smart-go-web は Git ルートの下にあります。

D:\workspace\drone\cloudsmartgo

UI のプロジェクトが Git ルートである一方、スレッドの行で D:\workspace\drone\cloudsmartgo\smart-go-web が使われている場合、グローバル状態のマッピングが正しく見えていても、サイドバーが空のままになることがあります。

  1. その場合は、一致するプロジェクトのセッションだけをリペアレントします。

    • state_5.sqlite をバックアップします
    • 変更されるすべての sessions/**/*.jsonl をバックアップします
    • threads.cwd を更新します
    • JSONL 内の session_meta.payload.cwd と turn_context.payload.cwd の項目を更新します
    • .codex-global-state.json のプロジェクトマッピングを表示ルートに更新します
  2. 新しいテスト会話は表示されるものの、同じプロジェクト内の古い会話が表示されない場合:

    • thread/list と cwd=<project-root> を指定して、新しい app-server に問い合わせます。新旧両方のセッションが返される場合、データは復元されています。
    • updated_at でグローバルな thread/list に問い合わせます。古いセッションが最初のページより後(たとえば 146 位)にランクされている場合、UI はそのメタデータをまだ読み込んでいません。
    • サイドバー表示処理を実行します。各プロジェクトのスレッドを少なくとも数件、最近の最初のページに表示するには、上限付きの形式を使用します。
$py = "C:\Users\admin\.cache\codex-runtimes\codex-primary-runtime\dependencies\python\python.exe"
$skill = "C:\Users\admin\.codex\skills\codex-session-recovery"
& $py "$skill\scripts\surface_codex_sidebar_threads.py" --per-project 2 --max-total 50
& $py "$skill\scripts\surface_codex_sidebar_threads.py" --per-project 2 --max-total 50 --write --report-path "C:\tmp\codex-sidebar-surface.json"
  • ピン留め/ピン留め解除のテストで、UI が読み込み済みの古いスレッドを表示できるものの、再起動後に表示されなくなることが確認できた場合は、すべてのセッションを最近の一覧に昇格させないでください。すべてのセッションを昇格させると、大規模なプロジェクトが再び最初の 50 行を占めることがあります。上記の上限付きラウンドロビン形式(--per-project 2 --max-total 50)を使用し、各プロジェクトの代表的なスレッドが最近の最初のページに表示されるようにします。

  • すべてのセッションを対象にする形式は、UI の読み込み手順ではなく、メタデータの正規化処理としてのみ使用してください。

$py = "C:\Users\admin\.cache\codex-runtimes\codex-primary-runtime\dependencies\python\python.exe"
$skill = "C:\Users\admin\.codex\skills\codex-session-recovery"
& $py "$skill\scripts\surface_codex_sidebar_threads.py" --per-project 0 --max-total 0 --write --report-path "C:\tmp\codex-sidebar-surface-all.json"
  • すでに 1~2 件の会話が表示されているものの、さらに履歴を表示する必要があるプロジェクトでは、対象を絞ったシード処理を実行します。ほかのプロジェクトが削除またはアーカイブされることはありませんが、大きな値を指定すると、最近の最初の 50 行からほかのプロジェクトが押し出されることがあります。まずは 10~15 を指定し、その結果ほかのプロジェクトが非表示になった場合は、上限付きのグローバルシードを再実行してください。
$py = "C:\Users\admin\.cache\codex-runtimes\codex-primary-runtime\dependencies\python\python.exe"
$skill = "C:\Users\admin\.codex\skills\codex-session-recovery"
& $py "$skill\scripts\surface_codex_sidebar_threads.py" --project-root "D:\workspace\ai-workspace\linux-web-mysql" --per-project 10 --max-total 10
& $py "$skill\scripts\surface_codex_sidebar_threads.py" --project-root "D:\workspace\ai-workspace\linux-web-mysql" --per-project 10 --max-total 10 --write --report-path "C:\tmp\codex-sidebar-surface-linux-web-mysql.json"
  • 同じプロジェクトの次のバッチを表示するには、ほかのプロジェクトが一時的に再び空に見える可能性をユーザーが受け入れる場合を除き、1 つのプロジェクトに 50 を設定しないでください。--offset-per-project を使用してプロジェクトのページを切り替えます。たとえば、最新の 10 件を表示した後、次のコマンドで 11~20 件目を表示します。
$py = "C:\Users\admin\.cache\codex-runtimes\codex-primary-runtime\dependencies\python\python.exe"
$skill = "C:\Users\admin\.codex\skills\codex-session-recovery"
& $py "$skill\scripts\surface_codex_sidebar_threads.py" --project-root "D:\workspace\ai-workspace\linux-web-mysql" --offset-per-project 10 --per-project 10 --max-total 10
& $py "$skill\scripts\surface_codex_sidebar_threads.py" --project-root "D:\workspace\ai-workspace\linux-web-mysql" --offset-per-project 10 --per-project 10 --max-total 10 --write --report-path "C:\tmp\codex-sidebar-surface-linux-web-mysql-page-2.json"
  • --offset-per-project は、昇格するバッチを変更することで、固定された最初のページのキャッシュを回避します。Codex Desktop 内部の thread/list limit: 50 を変更するものではありません。対象ページの表示後、ほかのプロジェクトが非表示になった場合は、上限付きのグローバルシードを再実行してください。

  • 書き込みモードの後に Codex Desktop を再起動し、サイドバーの最近のスレッドのキャッシュを再構築します。

コマンド

通常の python が利用できない場合は、同梱の Python を使用します。

$py = "C:\Users\admin\.cache\codex-runtimes\codex-primary-runtime\dependencies\python\python.exe"
$skill = "C:\Users\admin\.codex\skills\codex-session-recovery"
& $py "$skill\scripts\restore_codex_project_sessions.py" --project-root "D:\workspace\drone\cloudsmartgo\smart-go-web"

state_5.sqlite がロックされている場合や、古いスクリプトの SQLite レポート処理でエラーが発生する場合に便利な、グローバル状態のみの復旧です。

$py = "C:\Users\admin\.cache\codex-runtimes\codex-primary-runtime\dependencies\python\python.exe"
$skill = "C:\Users\admin\.codex\skills\codex-session-recovery"
& $py "$skill\scripts\recover_codex_global_state.py" --project-root "D:\workspace\drone\cloudsmartgo\smart-go-web" --project-display-root "D:\workspace\drone\cloudsmartgo" --write

app-server の thread/list.cwd の完全一致が根本原因と疑われる場合に、セッションの親を変更します。

$py = "C:\Users\admin\.cache\codex-runtimes\codex-primary-runtime\dependencies\python\python.exe"
$skill = "C:\Users\admin\.codex\skills\codex-session-recovery"
& $py "$skill\scripts\reparent_codex_sessions.py" --old-root "D:\workspace\drone\cloudsmartgo\smart-go-web" --new-root "D:\workspace\drone\cloudsmartgo" --write

プロジェクトのルートを変更せずに、Windows の \\?\ cwd プレフィックスを正規化します。

$py = "C:\Users\admin\.cache\codex-runtimes\codex-primary-runtime\dependencies\python\python.exe"
$skill = "C:\Users\admin\.codex\skills\codex-session-recovery"
$root = (Get-Location).Path
& $py "$skill\scripts\reparent_codex_sessions.py" --old-root $root --new-root $root --write

書き込みモード:

$py = "C:\Users\admin\.cache\codex-runtimes\codex-primary-runtime\dependencies\python\python.exe"
$skill = "C:\Users\admin\.codex\skills\codex-session-recovery"
& $py "$skill\scripts\restore_codex_project_sessions.py" --project-root "D:\workspace\drone\cloudsmartgo\smart-go-web" --write

UI の cwd を完全に正規化する Windows の書き込みモード:

$py = "C:\Users\admin\.cache\codex-runtimes\codex-primary-runtime\dependencies\python\python.exe"
$skill = "C:\Users\admin\.codex\skills\codex-session-recovery"
& $py "$skill\scripts\restore_codex_project_sessions.py" --project-root (Get-Location).Path --write --normalize-windows-extended-paths

ユーザーが Codex Desktop をすでに完全に終了している場合は、書き込みモードを安全に実行できます。Codex がまだ実行中で、ユーザーがリスクを明示的に了承している場合:

& $py "$skill\scripts\restore_codex_project_sessions.py" --project-root "D:\workspace\drone\cloudsmartgo\smart-go-web" --write --allow-running-codex

実行中の Codex インスタンスが原因で安全に書き込めない場合は、同梱の外部 PowerShell ヘルパーを起動します。既定では現在のディレクトリを ProjectRoot として使用し、すべての Codex/codex プロセスが終了するまで待機してから、復旧を実行し、同じルート内の cwd 値を正規化して、結果を検証します。

$skill = "C:\Users\admin\.codex\skills\codex-session-recovery"
Start-Process -FilePath powershell.exe -ArgumentList @("-NoProfile","-ExecutionPolicy","Bypass","-File","$skill\scripts\run_recovery_after_codex_exit.ps1","-ProjectRoot",(Get-Location).Path) -WindowStyle Hidden

ログに Waiting for Codex processes to exit... とだけ表示されている場合は、Codex プロセスがまだ実行中です。次のコマンドで確認してください。

Get-Process | Where-Object { $_.ProcessName -match '^(Codex|codex)$' }

ユーザーがエージェントに Codex の終了を明示的に依頼した場合、またはヘルパーが正常な終了を確認する前に Codex が自動再起動を繰り返す場合は、外部プロセスから -StopCodexFirst を指定してヘルパーを使用します。

$skill = "C:\Users\admin\.codex\skills\codex-session-recovery"
Start-Process -FilePath powershell.exe -ArgumentList @("-NoProfile","-ExecutionPolicy","Bypass","-File","$skill\scripts\run_recovery_after_codex_exit.ps1","-ProjectRoot",(Get-Location).Path,"-StopCodexFirst") -WindowStyle Hidden

復旧後の書き込み時に、古いセッションもサイドバーの最近使った項目のキャッシュに表示するには:

$skill = "C:\Users\admin\.codex\skills\codex-session-recovery"
Start-Process -FilePath powershell.exe -ArgumentList @("-NoProfile","-ExecutionPolicy","Bypass","-File","$skill\scripts\run_recovery_after_codex_exit.ps1","-ProjectRoot",(Get-Location).Path,"-StopCodexFirst","-SurfaceSidebar","-SurfacePerProject","2","-SurfaceMaxTotal","50") -WindowStyle Hidden

復元したすべてのインタラクティブセッションでメタデータを正規化するには、-SurfacePerProject 0 -SurfaceMaxTotal 0 を使用します。多数の JSONL ロールアウトファイルが更新される可能性がありますが、これは上限を設けた最初のページの UI ハイドレーション手順の代わりにはなりません。全セッションの正規化後に、-SurfacePerProject 2 -SurfaceMaxTotal 50 を指定して、上限付きの表示処理を再度実行してください。

特定のプロジェクトがすでに表示されているものの、最初の 1~2 件より多くの会話が必要な場合は、対象を絞った表示処理に -SurfaceProjectRoot の値を 1 つ以上指定します。合計数は 10 などの控えめな値にしてください。単一のプロジェクトに 50 を設定すると、最近使った項目の最初のページが埋まり、他のプロジェクトが再び空に見える場合があります。

$skill = "C:\Users\admin\.codex\skills\codex-session-recovery"
Start-Process -FilePath powershell.exe -ArgumentList @("-NoProfile","-ExecutionPolicy","Bypass","-File","$skill\scripts\run_recovery_after_codex_exit.ps1","-ProjectRoot",(Get-Location).Path,"-StopCodexFirst","-SurfaceSidebar","-SurfaceProjectRoot","D:\workspace\ai-workspace\linux-web-mysql","-SurfacePerProject","10","-SurfaceMaxTotal","10") -WindowStyle Hidden

次の対象ページを表示するには、-SurfaceOffsetPerProject を追加します。この例では、linux-web-mysql の項目 11~20 を表示します。

$skill = "C:\Users\admin\.codex\skills\codex-session-recovery"
Start-Process -FilePath powershell.exe -ArgumentList @("-NoProfile","-ExecutionPolicy","Bypass","-File","$skill\scripts\run_recovery_after_codex_exit.ps1","-ProjectRoot",(Get-Location).Path,"-StopCodexFirst","-SurfaceSidebar","-SurfaceProjectRoot","D:\workspace\ai-workspace\linux-web-mysql","-SurfaceOffsetPerProject","10","-SurfacePerProject","10","-SurfaceMaxTotal","10") -WindowStyle Hidden

ヘルパーへの引き継ぎをすぐに確認します。

$root = (Get-Location).Path
$safeName = ($root -replace '^[A-Za-z]:\\?', '' -replace '[\\/:*?"<>| ]+', '-').Trim('-')
$log = Join-Path $root ".codex-session-recovery-$safeName.log"
Start-Sleep -Seconds 2
if (-not (Test-Path -LiteralPath $log)) {
    Get-Process powershell -ErrorAction SilentlyContinue | Select-Object Id,StartTime,Path
    Get-Process | Where-Object { $_.ProcessName -match '^(Codex|codex)$' } | Select-Object Id,ProcessName,Path
    throw "Recovery helper did not create its log; use explicit -LogPath or UAC helper."
}
Get-Content -LiteralPath $log -Tail 20

ユーザーが自動復旧に同意しており、プロセス環境に Path と PATH の両方が含まれているため通常の Start-Process が失敗する場合は、ヘルパーを起動する前に、プロセスレベルの重複キーを削除します。

$envs = [System.Environment]::GetEnvironmentVariables("Process")
if ($envs.Contains("Path") -and $envs.Contains("PATH")) {
    $pathValue = $envs["Path"]
    [System.Environment]::SetEnvironmentVariable("PATH", $null, "Process")
    [System.Environment]::SetEnvironmentVariable("Path", $pathValue, "Process")
}
$skill = "C:\Users\admin\.codex\skills\codex-session-recovery"
Start-Process -FilePath "C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe" -ArgumentList @("-NoProfile","-ExecutionPolicy","Bypass","-File","$skill\scripts\run_recovery_after_codex_exit.ps1","-ProjectRoot",(Get-Location).Path,"-StopCodexFirst") -WindowStyle Hidden

Stop-Process が Access is denied で失敗する場合は、UAC を使用して、昇格した権限でヘルパーを実行することをユーザーに求めてください。

$skill = "C:\Users\admin\.codex\skills\codex-session-recovery"
$script = "$skill\scripts\run_recovery_after_codex_exit.ps1"
$root = (Get-Location).Path
$log = "C:\tmp\codex-session-recovery-$((Split-Path -Leaf $root) -replace '[\\/:*?""<>| ]+', '-').log"
$args = "-NoProfile -ExecutionPolicy Bypass -File `"$script`" -ProjectRoot `"$root`" -LogPath `"$log`" -StopCodexFirst"
Start-Process -FilePath "C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe" -ArgumentList $args -Verb RunAs -WindowStyle Normal

一時的なヘルパースクリプトを作成する場合、Codex が起動したプロセスから taskkill /T を使用しないでください。復旧の実行前にヘルパー自体が終了してしまう可能性があります。/T を付けずに taskkill /F /IM Codex.exe と taskkill /F /IM codex.exe を使用してから、復旧と検証のコマンドを実行してください。

出力の解釈

  • ドライランモードで write_performed: false となるのは想定どおりです。
  • missing_from_session_index: 0 は、古い軽量インデックスが修復されたことを意味します。
  • missing_global_hints: 0 と missing_project_assignments: 0 は、サイドバー/プロジェクトの状態に対象のマッピングがあることを意味します。
  • cwd_exact_match_risk: false は、SQLite の threads.cwd の値が UI のプロジェクトルートと文字列として完全一致していることを意味します。これは任意の診断項目ではなく、成功条件の一部として扱ってください。
  • codex_processes_running が空でなく、書き込み後もグローバル状態のフィールドが不足している場合、Codex がメモリ上の内容でファイルを上書きした可能性が高いです。Codex を完全に終了し、スクリプトを外部から実行してください。
  • これらのカウントがゼロなのに UI にスレッドが表示されない場合は、app-server の thread/list と UI のプロジェクトルートの間で cwd が完全一致していない可能性を疑ってください。
  • missing_* のカウントがゼロで、グローバル状態にプロジェクトが含まれているのに UI が空のままの場合は、state_5.sqlite で \\?\D:\... のような threads.cwd の値を確認してください。同じルートへの再割り当てが必要です。UI のフィルターは文字列の完全一致で照合されることがあります。
  • ログに Done. と表示されても、期待される再割り当ての手順が含まれていない場合は、スクリプト更新前にバックグラウンドプロセスが起動しています。新しい待機スクリプトを起動してください。
  • ログが Stopping Codex processes... の直後に止まる場合は、ヘルパーが自身の終了コマンドによって強制終了されたか、権限の問題でブロックされている可能性があります。上記の自動終了/再起動の手順を使用してください。

コメント