Skip to content

About

Find any coding-agent session and continue it in any agent. Local-first CLI and TUI for Claude Code, Codex, OpenCode, Pi, Grok, Cursor, Antigravity, and Hermes.

Topics

Resources

Code of conduct

Contributing

Security policy

Stars

5 stars

Watchers

0 watching

Forks

Repository files navigation

OmniSession logo

OmniSession

Find any coding-agent session. Continue it in any agent.

omni is a local-first CLI and terminal picker that searches your Claude Code, Codex, OpenCode, Pi, Oh My Pi, Grok, Cursor, Antigravity, and Hermes history, then continues the session you pick in the agent you want next.

CI status Provider conformance status Latest release MIT license Platforms: Linux, macOS, Windows preview

Website · Quick start · Compatibility · Architecture · Docs

Synthetic demo: code a rate limiter in Codex, run omni and pick that session and Claude Code, then write the README with the visible history. The original session stays intact.

Code in Codex. Docs in Claude. Run omni, pick the session, then choose Claude Code.
Synthetic sessions and illustrative responses. Commands and tool calls stay historical and never replay.
Still preview · Session browser

Quick start

# Install on Linux or macOS: checksum-verified, adds `omni` and provider shims
curl -fsSL https://raw.githubusercontent.com/bvolpato/omnisession/main/install.sh | sh

# Browse every agent's sessions, pick one, choose where it opens
omni

# Search without opening the picker
omni search "rate limiter"

# Continue a Claude Code session in Codex
omni resume claude:<session-id> --in codex

On Windows x86-64 (preview), see Install.

Features

Continue any session in any agent

  • Native imports where accepted. OmniSession writes a new session in the target agent's own format, through the agent's import interface or a native writer. Every native import is verified by read-back, and a failure rolls back exactly what was created. Supported agents lists each route and minimum version.
  • You decide when an import cannot run. On a terminal OmniSession says why and asks: retry (after closing the agent that blocked it, say), fork in the source agent instead, continue with a handoff file, or cancel. Routed shim commands ask too. It never quietly swaps the import you asked for.
  • Semantic handoff as the fallback. A handoff starts a fresh target session from a private file that quotes redacted history as untrusted context. Scripts and pipes, where nobody can answer, fall back to it automatically.
  • History, never replay. Tool calls and shell commands carry over as historical records and never run again. Approvals, hidden reasoning, and permission state stay out.
  • Same agent, native paths. Same-agent sessions resume in place or fork through the agent's own commands.
omni resume codex:<session-id> --in claude-code
omni fork <session> --in opencode
omni inspect <session> --target grok   # what gets preserved, summarized, or omitted

One picker for every agent's history

  • Run omni. Sessions from every installed agent appear in one list, current workspace first. Related sessions stay grouped as a tree across agents.
  • Fuzzy and full-text. Titles, folders, branches, and IDs match fuzzily as you type. Conversation text matches come from a local, redacted full-text index. Quoted text matches exactly.
  • Delta indexing. The first run indexes every discovered session. Later runs index only sessions that changed since the last index.
  • Scriptable. omni search works without the picker, and --json returns structured results.
omni search pagination --all-projects --provider codex --limit 50
omni --json search pagination
omni search pagination --cached      # search without reading provider stores

Safe by design

  • Local-first. No daemon, telemetry, or hosted session service. Background update checks contact GitHub, and launched agents keep their own network behavior.
  • Read-only provider stores. Discovery, search, and transfers never write source stores. The only source change is deleting the exact session you select and confirm.
  • Guarded deletion. Private-store deletion validates exact paths and schemas, refuses while that agent runs, and verifies the session is gone.
  • Redacted by default. The search index, handoffs, imports, Markdown exports, and bundles redact recognized credential fields and patterns, and known provider authentication files are never read. Redaction cannot prove every secret is absent, so review sensitive sessions before you transfer them.
  • Routing by identity. Workspace selection or an exact session ID decides routing. Recency does not.
  • Quiet output. CLI output leaves out transcript text unless you ask for it with show, markdown, export, search --show-text, or a transfer.
  • Ctrl+C rolls back. Interrupting a native import started from the picker, omni resume, omni fork, or a provider shim rolls back the generated target and exits without launching.

Full model: SECURITY.md and RFC 006.

Works where you work

  • Linux and macOS release binaries for x86-64 and ARM64, with a checksum-verified installer and background update checks.
  • Windows x86-64 preview with a checksum-verified PowerShell installer and compiled provider aliases.
  • Provider shims. claude --continue, codex resume, and other continuation commands route through omni once you select an OmniSession task for the workspace. Everything else passes straight through.
  • Portable bundles. Export a redacted bundle, import it on another machine, and continue it as imported:<bundle-uuid>.

Open and rigorous

  • Canonical event model. Every adapter maps native records onto one append-only event model with explicit replay policies (RFC 001).
  • Specified in RFCs. Workspace identity, adapter protocol, transfer modes, threat model, native materialization, and deletion each have an RFC.
  • Conformance matrix. Token-free conformance runs all 90 cross-agent import paths across ten agents in isolated homes, with installed-provider checks and synthetic private stores. Every cell must match the original trajectory.
  • Compatibility manifest. One reviewed manifest drives version gates, capability checks, the website, and the compatibility table.

Supported agents

Agent Import route Version gate Read/index Same-agent resume Cross-agent import
Codex Provider app-server import >= 0.146.0 Linux, macOS, Windows Linux, macOS, Windows Linux, macOS, Windows
Claude Code Transactional native writer >= 2.1.220 Linux, macOS Linux, macOS Linux, macOS
OpenCode Official import and export Official API (tested 1.18.18) Linux, macOS Linux, macOS Linux, macOS
Pi v3 JSONL native writer >= 0.79.3 Linux, macOS Linux, macOS Linux, macOS
Oh My Pi (omp) Pi-compatible v3 JSONL native writer >= 18.2.10 Linux, macOS Linux, macOS Linux, macOS
Grok ACP session import >= 0.2.114 Linux, macOS, Windows Linux, macOS, Windows Linux, macOS, Windows
Cursor IDE SQLite native writer >= 3.12.17 Linux, macOS Linux, macOS Linux, macOS
Cursor Agent SQLite/protobuf native writer >= 2026.07.23-e383d2b Linux, macOS Linux, macOS Linux, macOS
Antigravity CLI SQLite/protobuf native writer >= 1.1.8 Linux, macOS Linux, macOS Linux, macOS
Hermes Provider session import >= 0.19.1 Linux, macOS Linux, macOS Linux, macOS
Antigravity IDE None: read-only source (RFC 010 draft) Read-only (surveyed 2.2.1) Linux, macOS Not guaranteed Not guaranteed
  • Gated agents stay enabled on newer versions unless structural validation or read-back fails. Older versions cannot import natively (you decide what happens instead), and Cursor IDE builds below the gate are excluded from target choices. OpenCode imports through its official API without a version gate.
  • Cursor IDE declares no clean start, so failed Cursor IDE imports stop with an error instead of handing off.
  • The picker offers only runnable targets found on this machine. Session references use provider:id, and claude and claude-code are interchangeable.

COMPATIBILITY.md has version signals, clean-start support, validation evidence per platform, and provider-specific transfer details.

Install

Linux and macOS

curl -fsSL https://raw.githubusercontent.com/bvolpato/omnisession/main/install.sh | sh

The installer verifies the release checksum, installs omni into ~/.local/bin, installs provider shims, and adds the shim directory to PATH in your shell profile. Restart your shell afterwards.

Set OMNI_INSTALL_DIR to an absolute path to install elsewhere, or OMNI_NO_MODIFY_PATH=1 to leave shell profiles alone:

curl -fsSL https://raw.githubusercontent.com/bvolpato/omnisession/main/install.sh | OMNI_INSTALL_DIR="$HOME/bin" sh

Linux archives contain static musl binaries without a host glibc dependency. WSL is a separate Linux environment; use the Linux installer inside WSL.

Windows x86-64 (preview)

From PowerShell:

irm https://raw.githubusercontent.com/bvolpato/omnisession/main/install.ps1 | iex

The Windows installer verifies the release checksum and installs omni only. To opt into compiled provider aliases, run this, then follow the printed PATH guidance:

omni shim install --bin-dir "$env:LOCALAPPDATA\OmniSession\bin"
Windows preview caveats
  • Aliases are hard links, so replacing omni.exe leaves them on the old build. Rerunning the installer upgrades omni and relinks existing aliases. If you replace omni.exe another way, rerun omni shim install with the same --bin-dir; it relinks only aliases whose content identifies an older OmniSession build (never runs them) and refuses any other file.
  • Windows packaging, installer, CLI, and shims run in native Windows CI. Codex and Grok declare read/index, clean start, same-agent resume, and cross-agent import on Windows. Installed Codex, OpenCode, and Grok checks run without credentials; broader provider fidelity remains provisional.
  • Other agents do not declare cross-agent import on Windows. Picker targets without declared import continue through semantic handoff, while explicit omni resume --in still attempts native import.
  • Ctrl+Break counts as Ctrl+C during omni index, omni search, and native imports, and import helpers run on a hidden console of their own, so neither key reaches them.
  • Native Windows and WSL provider stores are not interchangeable.

From source

Requires Rust 1.88 or newer.

git clone https://github.com/bvolpato/omnisession.git
cd omnisession
cargo build --release --locked -p omnisession-cli
# then copy target/release/omni onto your PATH

Check this machine

omni doctor                     # installations, stores, state, and import version gates
omni adapters                   # declared capabilities; runs nothing
omni adapters --check-imports   # runs version probes: import=ready or import=blocked

Each command accepts --json.

omni doctor runs each installed CLI's version command, for 15 seconds at most, and reports old or unrecognized versions and failed probes as native-import blockers. Cursor IDE is read from static product metadata and is never launched. A version newer than the tested one is an advisory, not a limit. Passing the version gate does not certify the store format: schema, active-writer, rollback, and read-back checks still run at transfer time. Doctor never writes provider stores.

A blocked import asks what to do on a terminal and falls back to semantic handoff in scripts. Cursor IDE has no handoff, so its failed imports stop. When a transfer falls back, the warning prints the full cause.

Usage

Pick a session

omni
  • NEW SESSION starts a clean session in any installed agent with a supported clean-session launcher.
  • Type to filter titles, folders, branches, and IDs fuzzily. Conversation text matches come from the local search index, with matching context and highlighted terms. Quoted text matches exactly, as in omni search.
  • Current workspace sessions appear first. Tab includes every workspace; left and right arrows cycle source agents.
  • Select a session, then choose where it opens. When the target matches the source, you can resume in place or fork. On the target page, type to filter agents by name or any name --in accepts, such as grok, agy, or cur; Esc clears the filter. ← and → change the permission mode the agent starts in, and the page shows the mode and the exact flags it adds.
  • The details pane shows workspace, branch, trajectory size, model, reasoning mode, token usage, and conversation lineage when recorded.
  • Discovery warnings show as a footer badge, and ? opens help with every key and the full warning text.
Key Action
↑ ↓ or Ctrl-P Ctrl-N Move selection
PgUp PgDn Home End Jump through the list
Enter Continue selected session
Esc Clear search, then quit
Tab Toggle current or all workspaces
← → Change source agent
Delete or Ctrl-D Delete selected session (y deletes, n cancels)
Ctrl-U or Ctrl-W Clear search or last word
Shift-↑ Shift-↓ Scroll preview
? or F1 Show or hide help

The mouse works too: click selects, double-click opens, and the wheel scrolls.

While the picker is open, it indexes conversation text for every discovered session in the background (whole transcripts up to 16 MiB, head and tail of larger ones), and the header shows progress. omni index builds the same index without opening the picker. Ctrl+C stops it after the current session, and the next run continues where it left off.

Unreadable sessions are skipped by later index runs until their source changes; omni index --retry-failed reads them again.

The picker checks for releases in the background. The footer shows the installed version and an update badge when an update is available; press ? then u to update. Confirmation shows the executable path. Package-manager installs still update through their manager.

If the picker looks empty, omni doctor reports this-workspace vs all-workspace counts and any discovery notes. Press Tab for every workspace, or list without the current-project filter:

omni list --provider codex
omni list --all-projects --provider codex

Search

omni search "rate limiter"
omni search '"qwen3.8"'   # exact phrase
omni search pagination --all-projects --provider codex --limit 50
omni --json search pagination
  • Each run first indexes sessions that changed since the last index, in scope: current project by default, every workspace with --all-projects. --no-index searches only what is already indexed.
  • --cached skips provider stores entirely: it searches the cached session list and the existing index, so results can include sessions changed or deleted since the last refresh. Run omni index to refresh.
  • Every word must match. Plain words match titles, folders, branches, and IDs fuzzily, and conversation text by prefix.
  • Words with inner punctuation, like qwen3.8, feat/rate-limiter, or api_key, match without gaps: as a substring of a title, folder, branch, or ID, and as adjacent words in conversation text. qwen3.8 finds qwen3-8, but not qwen3 and 8 far apart.
  • Double quotes match exactly, ignoring case but keeping spaces and punctuation: "qwen3.8" finds Qwen3.8-Coder, but not qwen3 8 or qwen3-8. An unterminated quote runs to the end of the query, empty quotes are ignored, and a query needs at least one letter or digit. In conversation text, a quoted phrase must start at the beginning of a word.
  • Title, folder, branch, and ID matches rank first; conversation matches follow.
  • By default, output shows session reference, age, folder, and match kind. Titles often quote prompts, so titles, index coverage (complete, head-tail, or preview), and redacted conversation text around each match appear only with --show-text. JSON always reports coverage for conversation matches.
  • The first Ctrl+C during indexing stops after the current session and searches what is indexed so far; a second Ctrl+C exits immediately.

Continue or fork

omni resume <session> --in codex            # continue in another agent
omni resume claude:<session-id> --in codex  # qualify the provider when needed
omni fork <session>                         # fork, choosing the target interactively
omni fork <session> --in codex
  • Bare session IDs work when unique. Add the provider prefix when needed.
  • omni resume without a session opens the picker. --from <provider> and --all set its starting filters.
  • --materialize-only creates and verifies a supported native target session without launching it.
  • --dry-run shows what would happen without launching.
  • --mode default|accept-edits|auto|yolo sets the permission mode the agent starts in.
  • Transfers across different workspace roots fail closed unless you pass --allow-workspace-mismatch.

Permission modes

By default OmniSession passes no permission flags, so the target agent starts in its own default mode. To start it in a stronger mode, press → on the target page or pass --mode to omni resume, omni fork, or omni switch. Modes run from least to most permissive, and the arrows stop at either end.

Mode What the agent does Claude Code Codex Grok Cursor Agent Antigravity CLI OpenCode Hermes
default No flags: the agent's own settings decide no flag no flag no flag no flag no flag no flag no flag
accept-edits Edits apply without asking; commands still ask --permission-mode acceptEdits --permission-mode acceptEdits --mode accept-edits
auto Safe actions run on their own; the agent's own review still stops risky ones --permission-mode auto --approve-for-me --permission-mode auto --auto-review
yolo Nothing asks; every command runs --dangerously-skip-permissions --dangerously-bypass-approvals-and-sandbox --always-approve --force --dangerously-skip-permissions --auto --yolo
  • The built-in default is always default. auto and yolo are choices you make each time, and the page draws yolo in the danger color. OMNI_MODE=auto (or any mode) sets your own standing default where the agent has that mode.
  • Pi has no permission prompts to configure, and the IDEs take no launch flags, so they show no mode.
  • Oh My Pi offers default (no flags), always-ask (--approval-mode always-ask), accept-edits (--approval-mode write), and yolo (--approval-mode yolo). always-ask fails closed if the installed help cannot validate it.
  • OmniSession uses a mode only when the installed agent's --help lists its flag (and, where the help prints them, its value under that flag). An older agent steps down to the nearest mode it has, with a warning. The answer is cached per binary until the binary, OmniSession, or its mode definitions change; a probe that fails is never cached.
  • --mode also preselects the mode on the target page and outranks OMNI_MODE. On a short terminal the page scrolls so the selected agent and its mode stay on screen.
  • The launch line says which mode runs, for example Codex permission mode: auto (--approve-for-me). Transferred history is still untrusted context, so review a session before continuing it in yolo.

Oh My Pi is a separate agent, not a Pi alias: use omp with --in and omp:ID for session references. COMPATIBILITY.md covers its session roots and modes.

Export visible history for manual use:

omni markdown <session> -o session.md

Run omni --help for diagnostics and advanced commands.

Delete a session

Delete or Ctrl-D in the picker removes a supported session from its native source store. Every delete asks for confirmation: y deletes, n cancels.

  • Codex, OpenCode, Grok, and Hermes delete through their own commands.
  • On Linux and macOS, Claude Code, Pi, Cursor Agent, Cursor IDE, and Antigravity CLI use guarded private-store deletion, which refuses while that agent runs. Windows keeps command-based deletion only.
  • Claude Code deletion removes the transcript and sidecars named by the session ID. Shared prompt history in history.jsonl keeps its lines.

Details: RFC 009.

Provider shims

Shims let familiar continuation commands pick up your OmniSession task, even when its latest session lives in another agent. The Linux and macOS installer adds them automatically.

  • Unix aliases are claude, codex, opencode, grok, hermes, agy, pi, and cursor-agent, symlinked into ~/.omnisession/shims.
  • Routed forms are intentionally narrow, such as claude --continue, codex resume --last, and grok --resume. Everything else, including explicit native session IDs, passes through unchanged. RFC 005 has the full table.
  • Routing applies only when the workspace has a selected OmniSession task (omni task start, omni task bind). Without one, commands pass through.
  • Set OMNI_BYPASS=1 to bypass shims for one provider command.

Install or remove shims yourself (--bin-dir must contain the installed omni):

omni shim install --bin-dir "$HOME/.local/bin"
omni shim uninstall --bin-dir "$HOME/.local/bin"

Portable bundles

omni export <session> -o session.omnisession
omni import session.omnisession
omni resume imported:<bundle-uuid> --in codex

Bundles are redacted, versioned JSON (RFC 008, schema). Imported bundles become durable local sources addressed by exact imported:<bundle-uuid> locators. They stay searchable and resumable after the original native store is unavailable, and keep original provider and session provenance. Import never writes a provider store.

How it works

flowchart LR
  stores[("Agent session stores<br/>read-only")] --> adapters["Adapters<br/>discover and canonicalize"]
  adapters --> ir["Canonical event model"]
  ir --> index[("OmniSession state<br/>redacted search index")]
  index --> ui["omni picker<br/>omni search"]
  ir --> planner{"Transfer planner"}
  planner -->|"same agent"| resume["Native resume or fork"]
  planner -->|"import accepted"| native["Native import<br/>new ID, read-back,<br/>exact rollback"]
  planner -->|"otherwise"| handoff["Semantic handoff"]
  resume --> target["Target agent"]
  native --> target
  handoff --> target
Loading
  1. Adapters read each agent's native store read-only and map visible records onto the canonical event model.
  2. The store keeps OmniSession state, lineage, and a bounded, redacted full-text index under ~/.omnisession.
  3. The planner picks the safest available route: native resume or fork for the same agent, a documented import, a version-gated native writer, then semantic handoff (RFC 004). No transfer silently upgrades to a riskier mode.
  4. Native imports create a new session ID, read the result back before launch, and roll back only what they created on failure (RFC 007).

Read more in ARCHITECTURE.md and the RFC index.

Configuration

Variable Effect
OMNISESSION_HOME Moves OmniSession state (default ~/.omnisession)
OMNI_THEME light, dark, or mono picker palette
NO_COLOR Any non-empty value selects the mono palette
OMNI_NO_MOUSE 1 turns off picker mouse capture
OMNI_NO_UPDATE_CHECK 1 turns off background release checks
OMNI_BYPASS 1 bypasses installed shims for one provider command
OMNI_MODE Standing default permission mode instead of the agent's own: accept-edits, auto, or yolo, used where the agent has that mode. The target page and --mode still override it.
OMNI_SNAPSHOT_MAX_BYTES Largest provider SQLite database plus WAL copied into a private temporary snapshot (default 4 GiB). Larger stores fail closed.
OMNI_CLAUDE_BIN, OMNI_CODEX_BIN, OMNI_OPENCODE_BIN, OMNI_GROK_BIN, OMNI_HERMES_BIN, OMNI_ANTIGRAVITY_BIN, OMNI_PI_BIN, OMNI_CURSOR_AGENT_BIN Absolute path to a provider binary. An invalid override means not installed, never a PATH fallback.
OMNI_INSTALL_DIR, OMNI_NO_MODIFY_PATH Linux and macOS installer: install directory, and 1 to skip shell profile changes

Picker colors follow the terminal background. It reads COLORFGBG, then asks the terminal for its background color (OSC 11, at most about 100 ms), and falls back to the dark palette. Windows uses COLORFGBG only. OMNI_THEME overrides detection; non-empty NO_COLOR selects mono (bold, dim, underline, and reverse only).

FAQ

Does OmniSession change my original sessions? No. Provider stores are opened read-only, and a transfer writes a new session in the target agent. The only source change is deleting the exact session you select and confirm.

Does anything leave my machine? OmniSession has no telemetry or hosted service. The release check contacts GitHub, and OMNI_NO_UPDATE_CHECK=1 turns it off. An agent that continues a session receives the transferred history and keeps its own network behavior.

What carries over, and will tool calls run again? Ordered user and assistant messages plus bounded tool activity carry over. Tool calls and shell commands stay historical and never run again. omni inspect <session> --target <agent> reports what a specific route preserves, summarizes, or omits.

My agent is older than the version gate. What happens? The native import cannot run. On a terminal OmniSession asks whether to retry, fork in the source agent, continue with a handoff file, or cancel. Scripts fall back to the handoff. omni adapters --check-imports shows this before you try.

The picker is empty. Now what? Press Tab to include every workspace, or run omni doctor for per-workspace counts and discovery notes.

Is OmniSession affiliated with these agents? No. OmniSession is independent and not endorsed by the owners of the agents it supports.

Contributing

Contributions are welcome. CONTRIBUTING.md covers setup, validation, testing policy, and PR expectations, and docs/README.md indexes all documentation. Design changes start as RFCs.

cargo fmt --check
cargo clippy --locked --workspace --all-targets --all-features -- -D warnings
cargo test --locked --workspace --all-features

Security

Report vulnerabilities privately through GitHub private vulnerability reporting. Never open a public issue containing secrets or transcript data. SECURITY.md describes scope and the security model.

License

MIT

About

Find any coding-agent session and continue it in any agent. Local-first CLI and TUI for Claude Code, Codex, OpenCode, Pi, Grok, Cursor, Antigravity, and Hermes.

Topics

Resources

Code of conduct

Contributing

Security policy

Stars

5 stars

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages