The .lok file format¶
.lok is the portable LOKUST session artifact. It is plain JSON with a well-defined schema. A single file carries everything needed to resume a session on another device.
Two variants share the top-level structure:
- Coordination session — produced by
lokustd/lokust session export. Carries a 5-agent workflow, per-phase outputs, and metadata. - Shell session — produced by
lokust-shell-snapshotandlokust-tmux export. Carries terminal state, Claude Code conversation bundle, and optional tmux scrollback.
Both variants coexist. A tool reading a .lok should inspect the session.kind field to decide how to interpret it. Missing kind means "coordination session" (legacy default).
Coordination session¶
Produced by lokustd via /sessions/{id}/export.
{
"session": {
"id": "a3f8b2c1-6d4e-4086-b936-233f5b97e959",
"status": "completed",
"phases": [
{
"agent_id": "architect",
"name": "Architect Agent",
"status": "completed",
"output": "...full agent output (text)...",
"duration_ms": 30052,
"tokens_used": 1754
}
],
"current_phase_index": 4,
"total_duration_ms": 365295,
"total_tokens": 49793,
"created_at_ms": 1776042774000
},
"project_dir": "/Users/user/lokust-platform",
"created_by": "user",
"workflow_name": "iPad Streaming Portal",
"agent_prompts": [
{
"agent_id": "architect",
"system_prompt": "...",
"task_prompt": "..."
}
]
}
Top-level fields¶
| Field | Type | Description |
|---|---|---|
session |
object | The session body (see below) |
project_dir |
string | null | Original cwd where the session was created |
created_by |
string | USER env var at creation time |
workflow_name |
string | null | Custom workflow label |
agent_prompts |
array | null | Custom per-agent prompts if workflow_name is set |
session fields¶
| Field | Type | Description |
|---|---|---|
id |
string | UUID-v4 |
status |
string | idle | running | paused | completed | failed |
phases |
array | Per-agent phase records |
current_phase_index |
u32 | 0-based |
total_duration_ms |
u64 | Elapsed wall time since start |
total_tokens |
u64 | Sum of tokens_used across completed phases |
created_at_ms |
u64 | Unix epoch milliseconds |
phases[] fields¶
| Field | Type | Description |
|---|---|---|
agent_id |
string | Stable ID (e.g. architect) |
name |
string | Display name (e.g. Architect Agent) |
status |
string | queued | running | paused | completed | failed |
output |
string | Full agent output text (may be multi-KB) |
duration_ms |
u64 | Time this phase ran |
tokens_used |
u64 | input + output tokens from the Claude API |
Shell session¶
Produced by lokust-shell-snapshot and lokust-tmux export.
{
"session": {
"id": "shell-<uuid>",
"status": "snapshot",
"kind": "shell",
"created_at_ms": 1776042774000
},
"shell": {
"cwd": "/Users/user/lokust-platform",
"hostname": "using-a-computer.local",
"user": "user",
"shell": "zsh",
"env": { "TERM_PROGRAM": "ghostty", "LANG": "en_US.UTF-8", "...": "..." },
"env_dropped_count": 32,
"history_tail": [ "cmd1", "cmd2 with [REDACTED]", "..." ],
"history_redacted_lines": 3,
"terminal": {
"program": "ghostty",
"version": "1.3.1",
"term": "xterm-256color"
},
"multiplexer": { "kind": "tmux", "session": "myshell" } | null,
"git": {
"branch": "main",
"head": "abc123def456",
"dirty_files": 0,
"remote": "git@github.com:..."
},
"claude_code": {
"project_slot": "-Users-user-lokust-platform",
"sessions_logged": 4,
"memory_files": 10,
"project_path": "/Users/user/.claude/projects/-Users-user-lokust-platform"
},
"tmux_scrollback": {
"format": "text+base64",
"bytes": 337,
"data": "<base64>"
}
},
"bundle": {
"kind": "claude-code-project",
"format": "tar.gz+base64",
"uncompressed_bytes": 2345678,
"base64_bytes": 2403276,
"data": "<base64-encoded tar.gz>"
},
"created_by": "user",
"captured_via": "lokust-shell-snapshot"
}
Top-level fields¶
| Field | Type | Description |
|---|---|---|
session |
object | Session metadata (see below) |
shell |
object | Captured shell state |
bundle |
object | absent | Optional embedded data (Claude Code project) |
created_by |
string | Capturing user |
captured_via |
string | lokust-shell-snapshot or lokust-tmux |
session.kind¶
For shell sessions, always "shell". Coordination sessions do not set this field (absence implies coordination).
shell.env¶
Only safe env vars are kept. The filter allowlist is:
- Exact names: HOME, USER, SHELL, TERM, LANG, PWD, OLDPWD, EDITOR, PAGER, TERM_PROGRAM, TERM_PROGRAM_VERSION, COLORTERM, LC_ALL, LC_CTYPE, TMUX, TMUX_PANE, ZELLIJ, ZELLIJ_SESSION_NAME, CLAUDECODE_ENTRYPOINT, CLAUDE_PROJECT_DIR, XDG_CONFIG_HOME, XDG_DATA_HOME
- Prefix match: LC_*, XDG_*
Names containing TOKEN, KEY, SECRET, PASSWORD, PASSWD, CREDENTIAL, AUTH, PRIVATE are always dropped, overriding any allowlist match.
env_dropped_count reports the number of vars filtered out.
shell.history_tail¶
Last 200 lines of zsh or bash history, in order. zsh timestamp prefixes (: ts:dur;cmd) are stripped — only the command text is kept. Lines matching any secret pattern are replaced with [REDACTED] versions. history_redacted_lines reports how many lines were affected.
shell.multiplexer¶
Non-null when the capture happened inside tmux or zellij.
// tmux
{ "kind": "tmux", "socket": "/tmp/tmux-501/default,12345,0", "session": "myshell" }
// zellij
{ "kind": "zellij", "session": "myshell" }
shell.tmux_scrollback¶
Present when produced by lokust-tmux export. Base64-encoded text of tmux capture-pane -p -S - output — the full pane history.
bundle¶
Optional payload. When present for a shell session:
{
"kind": "claude-code-project",
"format": "tar.gz+base64",
"uncompressed_bytes": 2345678,
"base64_bytes": 2403276,
"data": "H4sIAAAAAAA..."
}
The tar contents are rooted at the project slot name (e.g. -Users-user-lokust-platform/...). lokust-shell-restore can rewrite the slot name during extraction when restoring to a different path.
Future bundle kinds (not yet emitted):
- editor-state — open files, cursor positions
- dotfiles-diff — changes to ~/.zshrc, ~/.gitconfig since baseline
Size guidance¶
| Variant | Typical size |
|---|---|
| Coordination session, 2/5 phases | 20–40 KB |
| Coordination session, 5/5 phases | 50–150 KB |
| Shell snapshot, no bundle | 5–10 KB |
Shell snapshot with --bundle |
1–5 MB |
| tmux export with scrollback + bundle | 2–5 MB |
These numbers assume typical agent output lengths (5–20 KB each) and 100–500 conversation messages in Claude Code's jsonl logs.
Versioning¶
A future format_version field will be added when the schema needs a breaking change. The current implementation does not emit it; readers should assume version 1 when absent and reject newer versions they don't understand.
Reading a .lok in code¶
Any JSON parser works. For strongly-typed access:
- Rust: see
lokust-daemon/src/session_store.rs(StoredSessionstruct) - Swift: see
ipad/LokustIpad/Models/LokFile.swift - Python:
json.load(open(path))is sufficient
Security¶
The capturing tool redacts known secret patterns before writing, but:
- Your shell history file on disk is untouched — rotate any leaked credentials
- The bundle contents are not scanned (Claude Code conversations may mention secrets)
.lokfiles should be treated with the same discretion as the source session itself — share over encrypted channels, don't commit to public repos