Skip to content

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:

  1. Coordination session — produced by lokustd / lokust session export. Carries a 5-agent workflow, per-phase outputs, and metadata.
  2. Shell session — produced by lokust-shell-snapshot and lokust-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 (StoredSession struct)
  • 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)
  • .lok files should be treated with the same discretion as the source session itself — share over encrypted channels, don't commit to public repos