# How to Resume Sessions from Codex in jcode

> Easily resume Codex sessions in jcode using the command line or Rust API. Reconnect to past conversations and load message history directly from JSONL files.

- Repository: [Jeremy Huang/jcode](https://github.com/1jehuang/jcode)
- Tags: how-to-guide
- Published: 2026-04-30

---

**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`](https://github.com/1jehuang/jcode/blob/main/src/cli/startup.rs) captures the value into the `resume_session_id` field of the `Args` struct.

```rust
// 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`](https://github.com/1jehuang/jcode/blob/main/src/tui/backend.rs), the system constructs a `Request::ResumeSession` containing your target ID and forwards it to the server.

```rust
// 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`](https://github.com/1jehuang/jcode/blob/main/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`](https://github.com/1jehuang/jcode/blob/main/src/tui/session_picker/loading.rs) scans the `~/.codex/sessions/` directory via the `load_external_codex_sessions` function.

```rust
// 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`.

```rust
// 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).

```bash

# 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`](https://github.com/1jehuang/jcode/blob/main/src/provider/openai.rs), the code appends the `--resume` flag to the provider command:

```rust
// 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`](https://github.com/1jehuang/jcode/blob/main/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.

```rust
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`](https://github.com/1jehuang/jcode/blob/main/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:

```rust
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`](https://github.com/1jehuang/jcode/blob/main/src/cli/startup.rs).
- **Session discovery**: jcode scans `~/.codex/sessions/*.jsonl` via `load_external_codex_sessions()` in [`src/tui/session_picker/loading.rs`](https://github.com/1jehuang/jcode/blob/main/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`](https://github.com/1jehuang/jcode/blob/main/src/tui/backend.rs).
- **Provider delegation**: The actual Codex binary receives the `--resume` argument constructed in [`src/provider/openai.rs`](https://github.com/1jehuang/jcode/blob/main/src/provider/openai.rs).
- **API support**: Call `client.resume_session(session_id)` from [`src/client/mod.rs`](https://github.com/1jehuang/jcode/blob/main/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`](https://github.com/1jehuang/jcode/blob/main/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`](https://github.com/1jehuang/jcode/blob/main/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`](https://github.com/1jehuang/jcode/blob/main/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.