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 inArgs.resume_session_idwithinsrc/cli/startup.rs. - Session discovery: jcode scans
~/.codex/sessions/*.jsonlviaload_external_codex_sessions()insrc/tui/session_picker/loading.rsand buildsSessionInfoobjects withResumeTarget::CodexSession. - Protocol layer:
Request::ResumeSessiontransmits the command from client to server viasrc/tui/backend.rs. - Provider delegation: The actual Codex binary receives the
--resumeargument constructed insrc/provider/openai.rs. - API support: Call
client.resume_session(session_id)fromsrc/client/mod.rsfor 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:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →