How to Resume Sessions from Codex in jcode

Run jcode --resume <session-id> to reconnect to any saved Codex conversation, or use the Rust API to send a Request::ResumeSession that loads message history from ~/.codex/sessions/*.jsonl files.

jcode (1jehuang/jcode) treats OpenAI Codex sessions identically to other external providers. When you need to resume sessions from Codex in jcode, the CLI parses your --resume flag into Args.resume_session_id, the backend issues a Request::ResumeSession, and the system rebuilds the conversation state from JSONL files stored in your local Codex directory.

Architecture of the Resume Flow

Resuming a Codex session flows through three distinct layers. Understanding this path clarifies why the same command works across headless scripts and interactive TUI sessions.

CLI Argument Parsing

When you append --resume <session-id> to your command, the parser in src/cli/startup.rs captures the value into the resume_session_id field of the Args struct.

// src/cli/startup.rs
Args {
    resume_session_id: Some(session_id), // filled when `--resume` is present
    // ...
}

Backend Request Transmission

The UI layer translates the CLI input into a protocol request. In src/tui/backend.rs, the system constructs a Request::ResumeSession containing your target ID and forwards it to the server.

// src/tui/backend.rs
let request = Request::ResumeSession { id: session_id };

This request serializes over the transport layer defined in crates/jcode-protocol/src/lib.rs.

Session Discovery and Loading

The server maintains an in-memory cache of SessionInfo objects built by load_sessions(). For Codex specifically, src/tui/session_picker/loading.rs scans the ~/.codex/sessions/ directory via the load_external_codex_sessions function.

// src/tui/session_picker/loading.rs
fn load_external_codex_sessions(scan_limit: usize) -> Vec<SessionInfo> {
    let root = crate::storage::user_home_path(".codex/sessions")?;
    // …collect_recent_files_recursive…
    .filter_map(|path| load_codex_session_stub(&path).ok().flatten())
}

The load_codex_session_stub helper reads the first JSON line of each .jsonl file, extracting the ID, timestamps, and working directory to populate a SessionInfo whose resume_target is ResumeTarget::CodexSession.

// src/tui/session_picker/loading.rs
Ok(Some(SessionInfo {
    id: format!("codex:{session_id}"),
    short_name: format!("codex {}", &session_id[..8]),
    icon: "🧠".to_string(),
    title: format!("Codex session {}", &session_id[..8]),
    resume_target: ResumeTarget::CodexSession {
        session_id,
        session_path: path.to_string_lossy().to_string(),
    },
    source: SessionSource::Codex,
    // ...
}))

Resuming from the Command Line

The simplest way to resume sessions from Codex in jcode is via the CLI. First list available sessions, then resume by supplying the raw session ID (without the codex: prefix).


# List available sessions (including Codex)

jcode --list

# Resume a specific Codex session

jcode --resume 019d-codex

When you execute --resume, the backend extracts the ResumeTarget from the matching SessionInfo and delegates to the OpenAI provider.

Provider-Specific Resume Implementation

Under the hood, jcode delegates the actual resumption to the Codex provider binary. In src/provider/openai.rs, the code appends the --resume flag to the provider command:

// src/provider/openai.rs (resume handling)
cmd.arg("--resume").arg(session_id);

The provider then streams historic messages back to the client, preserving the original model settings, token usage, and tool outputs. If the resume succeeds, the UI shows a notice like “Resumed ⧈ Codex session XYZ” emitted from src/tui/app/remote/server_events.rs. If no terminal opens automatically, you see the helpful prompt: jcode --resume <session_id>.

Resuming Programmatically via Rust API

For custom tooling, use the jcode client library to resume sessions without invoking the CLI directly.

use jcode::client::Client;
use anyhow::Result;

#[tokio::main]
async fn main() -> Result<()> {
    // Connect to the running jcode server (Unix socket or TCP)
    let mut client = Client::connect().await?;
    
    // Provide the raw Codex session id (no "codex:" prefix)
    let session_id = "019d-codex";
    
    // Initiate resume – returns the event id for tracking
    let resume_id = client.resume_session(session_id).await?;
    
    // Optional: wait for the full history to be streamed back
    client.wait_for_history(resume_id).await?;
    Ok(())
}

The resume_session method in src/client/mod.rs constructs the Request::ResumeSession internally and forwards it to the server.

Debugging Session Availability

If a session fails to appear in the picker, inspect the generated SessionInfo objects directly:

use jcode::session::load_sessions;

fn main() -> anyhow::Result<()> {
    let sessions = load_sessions()?;
    for s in sessions {
        if matches!(s.source, jcode::session::SessionSource::Codex) {
            println!("Codex session {} → {}", s.id, s.title);
        }
    }
    Ok(())
}

This outputs the prefixed ID format used internally (e.g., codex:019d-codex) and confirms the stub loader found your .jsonl files in ~/.codex/sessions/.

Summary

  • CLI entry point: Use --resume <id> to trigger the flow; the value is captured in Args.resume_session_id within src/cli/startup.rs.
  • Session discovery: jcode scans ~/.codex/sessions/*.jsonl via load_external_codex_sessions() in src/tui/session_picker/loading.rs and builds SessionInfo objects with ResumeTarget::CodexSession.
  • Protocol layer: Request::ResumeSession transmits the command from client to server via src/tui/backend.rs.
  • Provider delegation: The actual Codex binary receives the --resume argument constructed in src/provider/openai.rs.
  • API support: Call client.resume_session(session_id) from src/client/mod.rs for headless or programmatic session restoration.

Frequently Asked Questions

Where does jcode store Codex session metadata?

jcode reads Codex session data from your local ~/.codex/sessions/ directory, specifically parsing the .jsonl files created by the official Codex CLI. The load_codex_session_stub function in src/tui/session_picker/loading.rs extracts the session ID, timestamps, and working directory from the first JSON line of each file to construct the internal SessionInfo.

Why doesn't my Codex session appear in the jcode session picker?

Sessions only appear if they exist in ~/.codex/sessions/ and contain valid JSONL data. Run the debug snippet shown earlier to verify load_sessions() returns your target. If the session file is corrupted or located outside the default Codex path, jcode cannot construct the necessary SessionInfo with ResumeTarget::CodexSession.

Can I resume a Codex session without the CLI?

Yes. Use the Rust client API as demonstrated in src/client/mod.rs. Connect to the running jcode server via Client::connect(), then call resume_session(session_id) to issue the Request::ResumeSession programmatically. This bypasses the TUI and works in headless environments.

What happens if the resume fails?

If the Codex provider cannot reconnect (for example, if the session ID is invalid), the server emits an error event processed in src/tui/app/remote/server_events.rs. The UI displays a suggestion to retry with the exact command: jcode --resume <session_id>, ensuring you can copy-paste the correct syntax.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →