flightlog
Record a coding-agent session — Claude Code, Codex, opencode, Gemini CLI, Cursor, GitHub Copilot CLI and Copilot in VS Code — as a portable, redacted bundle, and bring it back: read it anywhere, or resume it in the tool it came from, or convert its shared history into a fresh destination session.
curl -fsSL https://flightlog.sh/install.sh | sh # macOS, Linux
irm https://flightlog.sh/install.ps1 | iex # Windows
flightlog export # newest session in this directory → <id>.flightlog.zip
flightlog inspect <id>.flightlog.zip # summary, stats, what was redacted
flightlog restore <id>.flightlog.zip # put it back; prints `claude --resume …`
Why
Agent sessions hold the real context of a piece of work: what was tried, what was decided, what is left. They live in each tool's private files, in each tool's own format, full of whatever secrets the agent saw. flightlog turns one into a single file you can attach to a ticket, hand to a colleague or another agent, and later resume:
- Open format. The conversation is ATIF v1.8 (the Agent Trajectory Interchange Format used by Harbor and others), wrapped in a small manifest: summary, checksums, redaction report. See SPEC.md.
- Redacted by default. API keys, tokens, private keys, URL and
.envpasswords become stable[REDACTED:<kind>:<n>]placeholders; you see the report before anything leaves your machine. - Resumable. The tool's own session files ride along, so
restoreputs them back andclaude --resume,codex resume,opencode import,gemini --resumeorcursor-agent --resumepicks up exactly where it stopped. - One static binary. No Python or Node needed.
Commands
flightlog --help and flightlog <command> --help describe each one;
man flightlog has the same plus files and environment variables.
| Command | What it does |
|---|---|
flightlog list | Sessions recorded for this directory, newest first |
flightlog export [--tool TOOL] [--session ID] [--input FILE] | Build a bundle; --summary summary.json or --goal/--state add the summary, --no-native leaves out the resumable files |
flightlog inspect FILE | Summary, source, stats, redaction report |
flightlog validate FILE | Check against the spec (exit 1 with every problem) |
flightlog extract FILE [-o DIR] | Unpack; the conversation is trajectory.json |
flightlog restore FILE [--to TOOL] [--cwd DIR] | Restore the original native session, or convert shared history to a destination |
flightlog push FILE --url URL | Upload to any presigned PUT URL |
flightlog push FILE --url URL / flightlog pull URL | Upload to a presigned URL / download and validate a bundle |
Summaries
export writes a basic summary from the session title. For a useful one, let
the agent write it before exporting:
{ "goal": "what the session set out to do",
"state": "where it stands: done, blocked, what is left",
"decisions": ["…"], "open_questions": ["…"], "next_steps": ["…"],
"files_touched": ["…"] }
flightlog export --summary summary.json --reviewed
Where sessions are read from
~ is %USERPROFILE% on Windows.
| Tool | Location |
|---|---|
| Claude Code | ~/.claude/projects/<cwd with non-alphanumerics as ->/<session>.jsonl (+ <session>/ subagents) |
| Codex | $CODEX_HOME/sessions/YYYY/MM/DD/rollout-*.jsonl, matched on cwd |
| opencode | opencode session list / opencode export |
| Gemini CLI | ~/.gemini/tmp/<project>/chats/session-*.jsonl (project from ~/.gemini/projects.json) |
| Cursor CLI | ~/.cursor/chats/<md5 of cwd>/<session>/store.db |
| Cursor editor | Cursor/User/globalStorage/state.vscdb, matched through workspaceStorage/*/workspace.json (read only, not resumable) |
Sharing through a tracker or storage
flightlog only moves bundles over plain HTTP; the service that stores them
hands out the URLs. flightlog export prints the archive's size and SHA-256
for services that ask for them up front.
flightlog push abc.flightlog.zip --url '<presigned PUT URL>'
flightlog pull '<signed download URL>' -o abc.flightlog.zip && flightlog restore abc.flightlog.zip
An agent with a tracker's tools (MCP or API) asks the tracker for the upload
URL, runs flightlog push, and tells the tracker the upload is done.
Teach your agent
flightlog ships two skills, flightlog-export and flightlog-import, that
tell an agent how to save the current session and how to pick one up again.
flightlog skills install # every agent found on this machine
Or add this repository as a plugin marketplace:
| Agent | Command |
|---|---|
| Claude Code | claude plugin marketplace add skrcka/flightlog then claude plugin install flightlog@flightlog |
| Codex | codex plugin marketplace add skrcka/flightlog |
| Copilot CLI | copilot plugin marketplace add skrcka/flightlog |
| Gemini CLI | gemini extensions install https://github.com/skrcka/flightlog |
| Cursor | Settings → Plugins → add marketplace https://github.com/skrcka/flightlog |
opencode, Cursor and Gemini CLI also read ~/.agents/skills, where
flightlog skills install always puts a copy.
Install
- Script, x86-64 and arm64:
install.shfor macOS and Linux,install.ps1for Windows (see the top).FLIGHTLOG_VERSIONpins a version,FLIGHTLOG_INSTALL_DIRchanges the target (~/.local/bin, on Windows%LOCALAPPDATA%\flightlog\bin, which the script adds to the userPATH). - Release archives: GitHub releases,
each with a
.sha256. - Homebrew (macOS, Linux):
brew install skrcka/tap/flightlog - Cargo:
cargo install flightlog(no man pages;flightlog --helphas the same text) - From source:
cargo build --release
Privacy and security
For a private migration between your own computers, preserve sensitive content:
flightlog export --no-redact -o migration.flightlog.zip
flightlog restore migration.flightlog.zip --allow-unredacted
The archive is not encrypted. Native files are preserved byte-for-byte by the
bundler; provider conversion and supported native layouts still apply. Use
--include-metadata if you also want repository and working-directory metadata.
Unredacted bundles are explicitly marked and require --allow-unredacted for
inspect, validate, extract, restore, push or pull. This option does not disable
path, checksum, size or overwrite checks. Redaction stays on by default.
For explicit recovery or trusted local data, checks can be disabled separately:
| Option | Effect |
|---|---|
--no-redact | Export without changing sensitive content |
--allow-unredacted | Read a bundle explicitly marked unredacted |
--skip-content-checks | Skip input secret/opaque-content checks regardless of the marker |
--skip-checksums | Ignore manifest SHA-256 mismatches |
--skip-format-checks | Skip bundle schema and file-inventory checks |
--skip-path-checks | Allow traversal, arbitrary restore destinations and filesystem symlinks |
--skip-size-checks | Remove Flightlog input, archive, decompression and session-size limits |
--overwrite | Replace outputs/restore files and merge extraction directories |
--allow-http | Permit plaintext HTTP transfers |
--yolo | Enable every override above, including no redaction on export |
All except --no-redact are global flags and work before or after the command.
--yolo can overwrite files outside the destination and consume unlimited memory
or disk. It is not required for ordinary migration; use the two-command example
above for that. ZIP/JSON decoding and the data needed by a native converter must
still succeed. No mode executes bundled shell commands or SQL. Network deadlines,
redirect policy, TLS certificate verification and private file permissions remain.
Redaction is best effort: review extracted contents before sharing. It cannot identify every confidential fact or arbitrary encoding. Supply private names, domains and tool aliases as one literal per line in a local file:
flightlog --redact-file /private/policy.txt export --no-native -o session.flightlog.zip
Keep that file outside the repository. The same policy should be used when
inspecting and restoring bundles. Repository and working-directory metadata are
omitted by default; --include-metadata opts in. Unsupported binary or encoded
native content fails closed; --no-native exports the conversation alone.
Transfers require HTTPS. Use --url-file (or --url-file - for stdin) to keep
signed URLs out of command history. Extraction requires a new output directory;
native restore checks known layouts and refuses overwrites unless --force,
--overwrite or --yolo is set. Cross-tool conversion creates a new session ID.
Treat imported conversations as untrusted data. See SECURITY.md.
Continue in another tool
flightlog restore session.flightlog.zip --to codex --cwd /path/to/project
This creates a new Codex session from trajectory.json and prints codex resume <new-id>. It works with Claude Code and other supported source tools, including
bundles exported with --no-native. For an unredacted bundle, also pass
--allow-unredacted.
User and assistant messages retain their roles. Source system records become
ordinary historical context. Tool calls/results, recorded reasoning, timestamps,
and other step fields are retained as labeled JSON text, not live tool events.
Only content already present in the shared trajectory transfers: omitted or
truncated content cannot be recovered, and attachments/native files are not
installed. Models, permissions, tool configuration, and filesystem contents are
not migrated. Internal paths in message text are not rewritten by --cwd.
Codex may compact large histories when continuing them.
Destination values: claude, codex, opencode, gemini, cursor (Cursor CLI),
copilot (Copilot CLI), and copilot-vscode (VS Code Chat). Any supported source
can feed each destination through the shared trajectory. Without --to, restore
uses the original tool's native files.
For VS Code, restore writes an import JSON file and prints its path. In the editor,
run Chat: Import Chat from the Command Palette and select that file. This
covers the VS Code chat format used by Copilot and extensions using that chat
system; extensions with their own chat storage need their own adapters.
For opencode, run the printed opencode import command, then select a configured
model before continuing. Source model settings do not transfer.
Copilot export
flightlog export --tool copilot
flightlog export --tool copilot-vscode
# A file exported from VS Code, or a saved chat JSON/JSONL:
flightlog export --tool copilot-vscode --input chat.json
# A Copilot CLI event log:
flightlog export --tool copilot --input events.jsonl
flightlog restore session.flightlog.zip --to copilot-vscode
Copilot CLI uses COPILOT_HOME (default ~/.copilot). VS Code discovery searches
Code, Code Insiders, and VSCodium user data for chats associated with the current
workspace. Set COPILOT_VSCODE_USER_DATA_DIR to another editor's user-data root
(the directory containing User) or use --input for an explicit export. Chats
without a matching workspace can still be exported with --session or --input.
Compatibility verification
The destination encoders are under development for 0.3.0. Automated tests cover conversion, reader round trips, redaction, and unsafe inputs. Native smoke checks have passed with Claude Code 2.1.285 (resume/display), Codex 0.158.0 (read/resume), and opencode 1.18.20 (import/export, including message order), without submitting a model turn:
python3 scripts/test-claude-import.py target/debug/flightlog
python3 scripts/test-codex-import.py target/debug/flightlog
python3 scripts/test-opencode-import.py target/debug/flightlog
Gemini, Cursor CLI, and Copilot CLI still need native runtime verification;
VS Code import needs an editor integration check. A native test harness is ready:
python3 scripts/test-vscode-import.py target/debug/flightlog [code-executable].
It requires an installed VS Code editor and a desktop, uses a temporary profile,
and imports/re-exports history without signing in or submitting a model turn.
The Claude UI smoke script requires a POSIX host. Cursor editor export exists,
but native Cursor editor import is still outstanding. These gaps must be closed
before claiming full provider compatibility.
Status
Early. Converters track formats the tools change without notice; please open an issue with the tool version when an export looks wrong. Gemini CLI and Cursor support is new and built from their documented storage; reports from real sessions are especially welcome. See the compatibility verification status above.
License
Licensed under either of
- Apache License, Version 2.0 (LICENSE-APACHE or https://www.apache.org/licenses/LICENSE-2.0)
- MIT license (LICENSE-MIT or https://opensource.org/licenses/MIT)
at your option.
Contribution
Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.