Skip to main content
Glama

Voyager ๐Ÿงญ

tests Python 3.10+ License: MIT platforms

One index across every AI coding agent on your machine.

Cross-agent continuity is built in: merge context across sessions and continue in any agent (voyager merge / switch / continue) โ€” see docs/ROADMAP.md for the shipped scope and docs/POST-1.0.md for what's next.

ไธญๆ–‡่ฏดๆ˜Ž

Voyager reads the local session data your agents already write โ€” Codex, Claude Code, ZCode, DSH (DeepSeek Harness), and more โ€” and turns it into a single searchable, exportable, resumable index. Pure local, no accounts, no cloud, no telemetry.

Voyager architecture: 8 agents, 8 storage formats, one index

Eight agents keep eight different formats; Voyager normalizes them into one SQLite index you can search, resume from, hand off to another agent, or query straight from inside an agent over MCP.

Voyager in action

$ voyager list
ID                                    PROV   UPDATED            MSG TOOL  TITLE
a1b2c3d4-...                          zcode  2026-09-13 01:13   162  206  ้‡ๆž„ๅญ˜ๅ‚จๅผ•ๆ“Ž็š„ๅ†™ๅ…ฅ่ทฏๅพ„
9f8e7d6c-...                          codex  2026-07-06 22:52    76  168  ไฟฎๅคๅคš็บฟ็จ‹ไธ‹่ฝฝๅ™จ็š„็ซžๆ€ๆกไปถ
5e4d3c2b-...                          claude 2026-07-17 12:46    89   70  ๅˆ†ๆžๆ•ฐๆฎ้›†็ป“ๆž„ๅนถ่ฎพ่ฎก่ฏ„ๆต‹่„šๆœฌ

Why

Every agent keeps its own history in its own format: Codex writes rollout JSONL, Claude Code writes project JSONL plus a file-version chain, ZCode uses SQLite, DSH compresses JSONL with zstd. You work across all of them โ€” Voyager makes that history one thing you can query.

  • Cross-agent timeline per repo โ€” what did all your agents do to this project, and when?

  • Full-text search everywhere โ€” find the session where someone ran that one command or touched that one file (CJK substring search works).

  • Real exports โ€” human-readable Markdown, or lossless JSON with both the normalized and the raw events.

  • Resume where you left off โ€” Voyager knows each platform's resume command and runs it for you.

Related MCP server: centered-agent-memory

Install

# isolated CLI install โ€” no virtualenv juggling (recommended)
pipx install "voyager[all] @ git+https://github.com/HarryHeYu/sessionFlow.git"

# or with pip (user-level)
pip install "voyager[all] @ git+https://github.com/HarryHeYu/sessionFlow.git"

# once the release is on PyPI (tracked in CHANGELOG.md)
pipx install voyager

[all] = DSH support (zstandard) + MCP server (mcp). The two are optional and only needed for those features:

pip install "voyager @ git+https://github.com/HarryHeYu/sessionFlow.git"          # core
pip install "voyager[dsh] @ git+https://github.com/HarryHeYu/sessionFlow.git"     # + DSH
pip install "voyager[mcp] @ git+https://github.com/HarryHeYu/sessionFlow.git"     # + MCP server

Working on Voyager itself:

git clone https://github.com/HarryHeYu/sessionFlow && cd sessionFlow
pip install -e ".[all,dev]"    # editable + extras + pytest
python -m pytest tests/ -q     # full dev env: 546 collected, 543 passed, 2 skipped, 1 deselected

Python โ‰ฅ 3.10. Windows / macOS / Linux. If voyager is not on your PATH, run it as python -m voyager.cli.

Usage

First run: voyager scan walks every supported agent's local storage and builds the index at ~/.voyager/index.db. After that, re-run scan whenever you want to pick up new sessions โ€” it is incremental and only re-reads what changed. To make syncing fully automatic, keep a watcher running (or put it in a scheduled task):

voyager watch --interval 300    # re-scan every 5 minutes, forever

Put the command in your OS autostart (or the provided ~/.voyager/watch.vbs in the Windows Startup folder) and the index stays current with zero manual steps.

voyager scan                # discover + index every supported agent
voyager list                # all sessions, newest first
voyager list --repo myproj  # sessions for one repo
voyager show <id>           # full message / tool-call timeline
voyager search "tensorboard"
voyager repo E:/code/myproj # cross-agent timeline for a repository
voyager export <id> --format md   # or --format json (includes raw events)
voyager resume <id>         # launches the native agent on that session
voyager handoff <id> --to codex   # context package for another agent
voyager continue            # one command to pick your latest work back up
voyager thread list         # WorkThreads: task-centric session groups
voyager switch codex        # switch the active thread to another agent
voyager skill install       # teach other agents about voyager
voyager brief               # 48h digest of what every agent is doing
voyager files <id>          # files the session touched
voyager diff <id>           # Claude sessions: rebuilt before/after diffs
voyager stats               # index statistics

Cross-agent handoff is work continuation, not session migration (the other agent cannot inherit hidden tool state or cached reasoning). voyager handoff <id> --to codex extracts the session into a Context Package (goal, instructions, files touched, commands, errors, where the work stopped) and shows the launch command; add --launch to start it. The target is told to read the package file and continue โ€” works for claude, codex and grok; other targets get the file to paste. Same-provider pickup still uses native resume (codex resume, โ€ฆ).

One command to continue: voyager continue picks your newest session and does the right thing โ€” native resume for codex/claude/dsh/grok, automatic handoff package for the rest. voyager continue --repo myproj --launch goes straight back into a specific project; multi-session synthesis (voyager merge A B C) groups the work into a WorkThread and cross-agent switch is one command (voyager switch codex โ€” lease aware, see docs/ROADMAP.md).

Goal-conditioned & budgeted: add --goal "finish adapter tests" to rank the evidence, and --budget compact|balanced|full|Nk to cap the bundle size (estimate printed). Without --goal/--budget the output is unchanged.

Transcript mode (opt-in, experimental): voyager switch codex --mode transcript writes a NEW native session containing a flattened user/assistant transcript (tools/state dropped) so the target resumes natively. Only codex/grok pass the resume gate today (claude timed out, dsh unverified) โ€” the default remains the Continuation Bundle. This is work continuation, not session teleportation: hidden tool state and provider runtime state never move.

Everyday flow โ€” brief to see what's moving, export to read one session in full (a 2,915-message DSH session โ†’ a 20 MB Markdown file), continue or handoff to pick it back up. Full recipes in docs/WORKFLOWS.md.

Session ids are matched by prefix; if a prefix is ambiguous Voyager lists the candidates and exits. resume runs the native agent's own command (e.g. codex resume <id>); providers without a CLI resume path say so explicitly instead of pretending.

Startup Continuity โ€” product status

Core functionality: Complete and operational.
Runtime auto-trigger: Claude Code, Grok and Codex have native SessionStart hooks, and Voyager registers them. Claude Code firing its hook is live-verified as of 2026-09-24, Grok as of 2026-09-25, and Codex as of 2026-09-28: a normally launched Codex session in the same repo received the tiered-v1 context before its first turn and continued the current WorkThread on a bare ็ปง็ปญ.

The startup_continuity() function correctly discovers WorkThreads, auto-attaches sessions, and compiles continuation context. What varies per provider is whether a session start can reach that function without the user doing anything.

Provider classification:

Codex is now on the native-hook path: voyager integrate install codex writes ~/.codex/hooks.json, and the fail-open handler emits the shared hookSpecificOutput.additionalContext envelope with tiered-v1 context before the first turn. Its handler, identity propagation, and idempotent lifecycle are covered by integration tests, and a live provider firing is verified (2026-09-28): hook delivery, native auto-attach, and zero-touch continuation.

Codex zero-touch continuity โ€” live-verified 2026-09-28:

Capability

Status

native SessionStart hook

PASS

tiered-v1 context delivery

PASS

zero-touch cross-agent continuity

PASS

native auto-attach

PASS

Open Codex normally in the same repo and type nothing but ็ปง็ปญ: it continues the current WorkThread without calling voyager_startup, voyager_continue, or any retrieval command.

Boundary: this is semantic continuity, not native transcript teleportation. The provider still starts a new native conversation; Voyager supplies the goal, the recent real work and the repository state โ€” not a replay of the previous session's hidden tool state.

Provider

Skill

MCP

Status

What it means

Claude

Y

R

H โ€” hook registered

Native SessionStart hook installed; the provider has been observed firing it live (2026-09-24). H is a static capability reading, not live evidence

Codex

Y

R

H โ€” hook registered

Native SessionStart hook installed; the provider has been observed firing it live (2026-09-28) and a bare ็ปง็ปญ continued the WorkThread with no Voyager command

Grok CLI

Y

N

H โ€” hook registered

Native SessionStart hook installed; the provider has been observed firing it live (2026-09-25). H is a static capability reading, not live evidence

DSH

Y

N

N โ€” no mechanism

Best effort

Single source of truth. The table below is published from voyager/capability_matrix.py, which is also what voyager doctor and voyager integrate status --deep read. Each cell is a declared capability capped by what this machine has actually observed, so the docs cannot claim a live verification the code never earned. Run voyager doctor to regenerate the machine's view of it.

WorkThread commands

voyager thread list|show|create|attach        # the basics
voyager thread activity <thread> [--json]     # who contributed what
voyager thread summarize <thread> [--json]    # one brief across every agent
voyager thread checkpoint <create|list|show|update|export|restore>
voyager thread close|reopen|archive <thread>  # explicit lifecycle
voyager thread stale [--days N] [--json]      # active but idle

A brief is a derivation over the canonical WorkThread -- deterministic, offline, and independent of any model: the authoritative fields come from the thread itself, the recent turns are grouped per agent and read oldest-first, and open items exist only because a checkpoint recorded them. reopen warns when it would leave two active threads for one repository, because ambiguity is a choice the user makes, never something a timestamp settles.

Dashboard

voyager dashboard [--out PATH] [--repo R] [--json]

Renders one self-contained HTML file (default ~/.voyager/dashboard.html): projects, WorkThreads, the active thread and its agent members, recent activity with a client-side filter, checkpoints, provider health and the open items. It is an observation panel, not a chat client -- no server, no CDN, no network requests, no JavaScript dependencies. Everything it shows comes from the same sources as voyager doctor and voyager thread summarize, so the page cannot tell a different story from the commands.

Observability commands

voyager doctor [--json]              # is this installation healthy, and why not
voyager verify [provider] [--json]   # declared / observed / effective per provider
voyager integrate status --deep      # every capability dimension, with its evidence

voyager db check   [--json]          # read-only integrity diagnosis
voyager db backup  [--json]          # consistent snapshot via SQLite's backup API
voyager db repair  [--json]          # plan by default; --apply runs the safe steps
voyager db compact [--json]          # VACUUM (maintenance, deliberately not "repair")

db repair never runs VACUUM โ€” that is db compact. db repair plans by default and --apply is the authorisation; there is no confirmation bypass.

Verification levels โ€” these are deliberately not the same claim:

Level

Meaning

SUPPORTED

Voyager can read the provider's session data

CONFIGURED

the provider's native startup hook is registered on this machine

UNIT_VERIFIED

the handler and envelope are covered by tests, and a real payload was driven through it end to end

LIVE_VERIFIED

the provider itself was observed firing the hook

ZERO_TOUCH_LIVE_VERIFIED

that, and a bare ็ปง็ปญ continued the WorkThread with no Voyager command

Provider

Startup surface

Level

Claude Code

native SessionStart

ZERO_TOUCH_LIVE_VERIFIED (2026-09-24)

Grok CLI

native SessionStart

ZERO_TOUCH_LIVE_VERIFIED (2026-09-25)

Codex

native SessionStart (~/.codex/hooks.json)

ZERO_TOUCH_LIVE_VERIFIED (2026-09-28, session 01a0e7a2-6b1f-7011-ad65-103e17fb1094: the tiered-v1 developer message arrived before the first ็ปง็ปญ, and that turn made zero voyager_* calls; the run's trace is in ~/.voyager/logs/codex-hooks.jsonl)

ZCode

native hooks (~/.zcode/cli/config.json, hooks.events.SessionStart)

UNIT_VERIFIED โ€” configured, and the handler was driven end to end with a real payload; a provider-fired run is still pending

Cursor

native hooks (~/.cursor/hooks.json, sessionStart)

UNIT_VERIFIED โ€” same

Kiro

native hooks (SessionStart / AgentSpawn, .kiro/hooks/*.json)

UNIT_VERIFIED โ€” handler written and driven end to end; hooks are project-scoped, so installing is a per-project choice

Antigravity

native hooks (PreInvocation, ~/.gemini/config/hooks.json)

UNIT_VERIFIED โ€” same, and injecting only on the first invocation

DSH

none found โ€” profiles/plugins/ACP only

SUPPORTED โ€” wrapper only

A unit test is never reported as a live verification here: ZCode, Cursor, Kiro and Antigravity are configured and their handlers are exercised against real payloads, but until the provider has actually fired the hook on this machine they stay at UNIT_VERIFIED.

Legend: Y = installed, R = registered, N = unsupported, A = available/manual setup needed.

Startup status: Y = zero-touch verified live, H = native hook registered, A = startup-assisted, N = no hook. The letter is derived from static capability and configuration only.

Live verification is now a separate, persisted thing: voyager verify reports, per provider, the declared state (what the code supports), the observed state (what this machine has actually seen, derived from an append-only verification_events table) and the effective state (the weaker of the two). Observation can only lower a claim, never raise it above what the code supports, and voyager verify is strictly read-only โ€” it cannot manufacture the evidence it reports. Run voyager doctor for the whole picture. Both Claude Code's trigger (2026-09-24) and Grok's (2026-09-25) have been observed live, and both still report H. Run voyager integrate status for the configuration answer on your machine.

How native hooks work here

Claude Code reads SessionStart hooks from ~/.claude/settings.json. Codex reads them from ~/.codex/hooks.json. Voyager writes the documented nested shape for each provider and preserves unrelated hooks:

{
  "hooks": {
    "SessionStart": [
      {
        "matcher": "startup",
        "hooks": [
          {"type": "command", "command": "\"<abs python>\" \"<abs>/claude_session_start.py\"", "timeout": 120}
        ]
      }
    ]
  }
}

voyager integrate install claude writes this for you (it is additive โ€” your own hooks are preserved, and the file is backed up first). The installed command uses absolute paths, so it does not depend on the interpreter being on PATH.

For Codex, voyager integrate install codex registers an absolute SessionStart command in ~/.codex/hooks.json. Codex passes its native session_id and cwd on stdin; Voyager responds with hookSpecificOutput.additionalContext using the shared tiered-v1 continuation format. The hook is fail-open and never blocks a Codex session if the index is unavailable.

Three things are verified. The handler is verified end-to-end: it emits a protocol-valid payload, caps the injected context at 9,000 UTF-16 code units, spills the full bundle to ~/.voyager/context/, and exits 0. The registration is verified: voyager integrate status reads the file back. And the provider firing the hook is verified too (2026-09-24) โ€” the manual run below recorded a SessionStart whose session_id belongs to Claude Code itself, not the verifier's synthetic one:

claude --debug hooks --init-only     # expect: Found 1 hook matchers in settings

That line was observed on 2026-09-24, and the real session_id it carried then completed the whole chain: transcript discovered โ†’ indexed โ†’ pending row resolved โ†’ session attached to WorkThread thr_0854d50b88, with no Voyager command. What is still unproven is that the model actually read and used the injected context, and no provider prints Y โ€” the CLI letter comes from static configuration, not from this observation. See docs/DOGFOOD.md for the evidence table.

What works right now โœ…

  • startup_continuity() handles discovery, attach, staleness detection

  • Auto-attach works when conditions are safe (exact repo match, single thread)

  • Context compilation reuses existing ranker+budget+continuation pipeline

  • A compiled context bundle is cached in the store and reused across session starts (5-minute TTL, invalidated by git changes or thread membership changes)

  • Ambiguity protection: explicit error if multiple active threads

  • Auto-registration creates config files for Codex/Claude (voyager integrate install <provider>), including the native Claude Code hook

How to use today ๐Ÿ”ง

Recommended workflows:

  1. Native hook (Claude Code): voyager integrate install claude, then restart Claude Code. No further action โ€” if the hook fires, context is injected before your first turn.

  2. Explicit commands: voyager switch <agent> or voyager continue [id]

  3. MCP-assisted: in-agent tool call voyager_startup(provider="codex", cwd="$PWD")

  4. Skill guidance: read SKILL.md in the agent's skill directory

A (startup-assisted) means: the runtime will not reach Voyager on its own, so you must invoke it via one of the workflows above. For Codex this no longer applies once voyager integrate install codex has registered the native SessionStart hook (live-verified 2026-09-28): the hook reaches Voyager before the first turn, so voyager_startup is not needed and should not be called โ€” startup context is the hook's job, and the skill is retrieval-only.

voyager integrate install claude   # skill + MCP + native SessionStart hook
voyager integrate install codex    # skill + MCP (~/.codex/config.toml)
voyager integrate status           # per-provider truth, including whether the hook is registered
voyager integrate remove claude    # removes only Voyager's entries, leaves your hooks alone

See docs/DOGFOOD.md for the detailed verification procedure.

Integration โ€” teach agents about Voyager

Install the Skill file into known agent directories:

voyager skill install      # installs SKILL.md at ~/.{agent}/skills/voyager/SKILL.md

The Skill instructs agents when to use Voyager commands and when NOT to (never export full sessions).

To register Voyager as an MCP server so agents can query it with native tools:

voyager integrate install codex    # skill + MCP (~/.codex/config.toml)
voyager integrate install claude   # skill + MCP + native SessionStart hook (~/.claude/settings.json)
voyager integrate status           # per-provider truth, incl. whether the hook is registered
voyager integrate remove <provider>  # undo every step (skill + mcp + bootstrap + hook)

These commands now auto-create config files if they don't exist - no manual setup needed for first-time installation. Re-running is idempotent, and install merges rather than overwrites: your own hooks and settings are preserved, and the file is backed up before it is rewritten.

For verification of actual zero-touch startup behavior, see docs/DOGFOOD.md and claude_continuity_verdict.md.

Supported platforms

Platform

Source

Messages

Tool calls

Shell exit

File diffs

Tokens

Resume

Codex (CLI/VSCode/Desktop)

rollout JSONL

โœ…

โœ…

โœ…

โŒ

โœ…

โœ… codex resume

Claude Code

project JSONL + file-history

โœ…

โœ…

โœ…

โœ… version chain

โœ…

โœ… claude --resume

ZCode

SQLite (~/.zcode/cli/db)

โœ…

โœ…

โœ…

โš ๏ธ file events (edits stay in raw)

โœ… usage tables

โŒ desktop only

DSH

zstd JSONL (~/.dsh/sessions)

โœ…

โœ…

โŒ

โŒ

โŒ

โœ… dsh --resume

Grok CLI

chat_history.jsonl + summary.json

โœ…

โœ…

โŒ

โŒ

โŒ

โœ… grok -r

Cursor

state.vscdb (SQLite)

โœ…

โœ…

โŒ

โš ๏ธ in raw

โš ๏ธ

โŒ IDE only

Kiro IDE

workspace-session JSON

โœ…

โŒ not persisted

โŒ

โŒ

โŒ

โŒ IDE only

Antigravity

conversation SQLite (protobuf)

โš ๏ธ heuristic

โš ๏ธ heuristic

โš ๏ธ text

โš ๏ธ snapshots on disk

โŒ

โŒ IDE only

Cursor and Antigravity adapters are marked experimental: Cursor reads its key-value store read-only and Antigravity decodes protobuf blobs heuristically (no public schema). Full per-field availability matrix and data-source paths for every tool are in docs/RECON.md.

Tests & CI

Adapters are the part of Voyager that breaks when a vendor ships a storage change, so every platform has a regression test against a synthetic fixture โ€” no real session data, no agent installation needed:

tests/
โ”œโ”€โ”€ fixtures/          # codex/claude/dsh/grok/kiro JSON+JSONL, zcode/cursor/antigravity SQL seeds
โ”œโ”€โ”€ conftest.py        # builds tmp trees (incl. zstd + SQLite) and repoints adapters at them
โ”œโ”€โ”€ test_codex.py  test_claude.py  test_zcode.py  test_dsh.py  test_grok.py
โ”œโ”€โ”€ test_cursor.py  test_kiro.py  test_antigravity.py  test_adapters.py
โ”œโ”€โ”€ test_store.py  test_export.py  test_handoff.py  test_cli.py  test_mcp.py
โ”œโ”€โ”€ test_claude_session_start_hook.py   # the SessionStart entrypoint: protocol, size cap, spill, logging
โ”œโ”€โ”€ test_codex_session_start.py         # Codex envelope, rollout-authoritative cwd
โ”œโ”€โ”€ test_zcode_session_start.py         # ZCode envelope, camelCase payload aliases
โ”œโ”€โ”€ test_cursor_session_start.py        # Cursor top-level additional_context, workspace_roots
โ”œโ”€โ”€ test_kiro_antigravity_session_start.py  # Kiro raw stdout, Antigravity injectSteps gating
โ”œโ”€โ”€ test_hook_payload.py                # the shared UTF-16 cap, both-ends cut, spill
โ”œโ”€โ”€ test_provenance.py                  # origin classification and the NULL sentinel
โ”œโ”€โ”€ test_l1_bands.py                    # STRONG/WEAK/UNKNOWN/BOOTSTRAP_ONLY and the scheduler
โ””โ”€โ”€ test_context_cache.py               # the persisted context cache, incl. hostile input
python -m pytest tests/ -q                # full dev env: 546 collected, 543 passed, 2 skipped, 1 deselected โ€” adapters, store, continuity, budget, leases, switch, skill, API, MCP, integration, provider hooks
python scripts/run_tests_core_only.py     # core-only simulated: a subset that skips the DB-backed suites

The two environments skip for different reasons, and the two numbers are not interchangeable. With the full dev extras the only 2 skips are data-dependent: tests/test_unicode_preservation.py reads the default local index and skips when it holds no Chinese-titled session (:33) or no sessions at all (:103). The core-only run adds 16 dependency-gated skips โ€” mcp, zstandard and PIL are absent, so test_continuity_tools.py, test_mcp.py, test_diagram.py and test_dsh.py skip. Neither class is a platform gate.

CI (.github/workflows/test.yml) runs the suite on Python 3.10โ€“3.13 (Linux) and 3.10/3.13 (Windows โ€” the adapters deal with %APPDATA%, drive letters and backslashes), plus a core-only job proving the CLI works with zero optional dependencies. The store tests cover the "don't wreck my thousands of sessions" contract: repeated scans never duplicate, changed sources are re-parsed, vanished sources are pruned.

Design

Provider files are read-only. Adapters translate each platform's events into one normalized model (Session / Event) while keeping the raw provider event alongside โ€” nothing is lost, giant blobs are truncated with a pointer back to the source. Everything lands in a local SQLite index with FTS5 (trigram, so CJK substring search works). Scans are idempotent: sources are tracked by (mtime, size) and re-parsed only when they change; sessions whose source files vanish are pruned.

Details in docs/ARCHITECTURE.md, docs/DECISIONS.md, docs/API.md and docs/FAQ.md and everyday recipes in docs/WORKFLOWS.md.

What's next

The Continuity Engine core is complete (see docs/ROADMAP.md for the full close-out). The post-1.0 backlog โ€” VS Code Context Composer UI, auto-clustering research, Claude/DSH transcript gates, scoped scan, fs-event watcher, PyPI/packaging polish โ€” lives in docs/POST-1.0.md.

Phased plan, CLI sketches, and the issue list: docs/ROADMAP.md ยท ไธญๆ–‡.

License

MIT โ€” see LICENSE.

Related MCP Connectors

Related MCP Servers

  • F
    license
    A
    quality
    D
    maintenance
    A persistent, cross-session knowledge base for AI agents that indexes session history into a searchable SQLite database with full-text search, enabling recall of past sessions, stored knowledge, and summaries.
    10
    -
  • A
    license
    Not graded
    quality
    C
    maintenance
    Enables searching, indexing, and recovering past AI chat sessions and agent actions from local AI coding tools, with optional vector database semantic search and direct filesystem access.
    -
  • F
    license
    Not graded
    quality
    B
    maintenance
    Enables AI coding agents to persistently store and retrieve conversation history with hybrid semantic and keyword search, cross-encoder reranking, session filtering, and archiving through MCP tools.
    -