Skip to content

CLI reference ​

sesh has two command forms: to <harness> (convert a session from one harness into another) and pull (merge Codex's new turns back into Claude). Both are non-destructive — they only ever write new session/rollout files — and both print a fidelity report before exiting.

On error, sesh prints sesh: <message> to stderr and exits with status 1.

sesh to <harness> [session file] [options] ​

Converts a session from a source harness into the target harness, so you can resume it there. Known harnesses today: claude-code (alias claude) and codex. The source defaults to the only other registered harness; with more than two registered, pass --from <harness>.

Shorthands:

  • sesh alone means sesh to claude (the original Codex → Claude direction);
  • sesh to-<harness> (e.g. sesh to-codex, sesh to-claude) is equivalent to sesh to <harness>.

Harnesses are pluggable: each one implements a single Harness interface (discover session files, parse them into the canonical message format, emit canonical messages into its native format, and describe how to resume) and registers itself. The to command is written purely against that interface, so adding a new harness never touches command code — see packages/sesh/src/core/harness.ts and packages/sesh/src/adapters/.

FlagEffect
session fileConvert this explicit source-session path instead of discovering one.
--from <harness>Source harness (default: the only other registered harness).
--listInteractively pick from discovered source sessions.
--allDon't filter discovery to the current directory.
--turns <n>Keep only the last n turns (dropped messages/orphaned tool results are counted and reported).
--dry-runDo everything except write the session file.
--launchAfter writing, exec the target harness's resume command directly.
-h, --helpShow usage.
-V, --versionShow version.

sesh / sesh to claude (Codex → Claude) ​

Converts a Codex session into a Claude Code session. With no path argument, discovers the newest rollout for the current directory.

Discovery. Scans $CODEX_HOME/sessions (default ~/.codex/sessions) for rollout-*.jsonl files, reads each one's session_meta for its cwd, and — without --list or --all — picks the most recent rollout whose cwd matches your current working directory's realpath.

Writes to $CLAUDE_CONFIG_DIR/projects/<munged-cwd>/<sessionId>.jsonl (default ~/.claude), where <munged-cwd> is Claude Code's own directory name mangling for the current working directory's realpath.

Prints claude --resume <sessionId> on success (or execs it directly with --launch).

sesh to codex (Claude → Codex) ​

Hands the newest Claude Code session for the current directory to Codex (sesh to-codex for short).

Discovery. Scans $CLAUDE_CONFIG_DIR/projects/<munged-cwd>/ (default ~/.claude) and — without --list or --all — picks the most recent session for the current directory's realpath.

Writes to $CODEX_HOME/sessions/<yyyy>/<mm>/<dd>/rollout-<timestamp>-<sessionId>.jsonl (default ~/.codex) — the exact layout codex resume <id> expects. The written rollout embeds a self-describing link marker at session_meta.payload.sesh: sourceSessionId, sourcePath, emittedLines — this is what lets sesh pull later find the handoff boundary without any external bookkeeping.

Prints codex resume <id> on success. Note that codex resume itself requires --skip-git-repo-check when run outside a git repository — that's Codex's own flag, sesh doesn't add it for you.

sesh pull [rollout.jsonl] [options] ​

After Codex has worked on a handed-off session (e.g. done a code review), merges the turns the other harness appended (Codex by default, Claude Code with --from claude) — everything past the emittedLines boundary recorded by to-codex, minus Codex's own boilerplate — into a copy of the original Claude session.

Discovery. Scans $CODEX_HOME/sessions for rollouts carrying a sesh link marker, and — without --all — picks the most recent one whose cwd matches the current directory's realpath.

FlagEffect
rollout.jsonlUse this explicit rollout path instead of discovering one.
--from <codex|claude>Which harness's session to pull new turns from (default codex). --from claude is the mirror flow: sessions emitted by sesh to claude now carry the same sesh link marker, so work done in Claude Code can be merged back into the source rollout and resumed with codex resume.
--allDon't filter discovery to the current directory.
--merge <raw|canonical>raw (default) byte-preserves the original session's lines — including its reasoning blocks — and appends only Codex's new turns. canonical re-emits the whole merged session from canonical messages: architecturally simpler and fully generic, but the original session's reasoning blocks are dropped (and reported).
--dry-runDo everything except write the merged session file.
--launchAfter writing, exec claude --resume <newId> directly.
-h, --helpShow usage.
-V, --versionShow version.

What gets written. A new copy of the original Claude session under $CLAUDE_CONFIG_DIR/projects/<munged-cwd>/<newSessionId>.jsonl: the original's lines are byte-preserved, only the sessionId is rewritten, and Codex's new turns are appended as a new chain whose first record's parentUuid points at the copy's last original line. The original session file, and the original rollout, are never modified.

Prints claude --resume <newId> on success.

Report vocabulary ​

Both commands print a short report before their final resume/launch line — a header naming the direction, then aligned key–value lines:

text
sesh: codex → claude-code

  rollout    rollout-2026-06-13T09-33-33-0d9dd699-….jsonl
  messages   187 ingested → 181 claude-code lines
  dropped    6 reasoning (opaque)
  settled    1 unanswered tool call
  truncated  kept last 3 turns (dropped 121 messages)
  size       ~14k tokens
  • messages N ingested → M … lines — how many source records were read vs. how many lines the emitter wrote (pull reports N new codex lines → M messages (K boilerplate filtered) instead).
  • dropped N reasoning (opaque/unfakeable) — reasoning blocks that can't survive the conversion (Codex's is usually encrypted-only; Claude's thinking blocks need a signature that can't be fabricated).
  • settled N unanswered tool calls — a session ending mid-turn on an unanswered tool call gets a synthesized placeholder result so the transcript stays valid.
  • truncated kept last N turns — printed when --turns was used.
  • size ~Nk tokens — an estimate of the resulting session's size, with a warning suggesting --turns when it's large (Codex's context is roughly 258k tokens, Claude's similar).