Skip to content

Shell capture & restore tools

Three scripts that extend LOKUST session portability to real terminal shells and Claude Code conversations. All live in session-vm/scripts/.

lokust-shell-snapshot

Capture a terminal session's restoration context as a .lok file.

Usage

lokust-shell-snapshot [--bundle] [--tmux SESSION] [output.lok]

Flags:

  • --bundle — embed the Claude Code project directory (~/.claude/projects/<slot>/) as a base64-encoded tar.gz inside the .lok. Enables conversation-level continuity across devices.
  • --tmux SESSION — reference a named tmux session (used by lokust-tmux export).

What it captures

Field Source
cwd os.getcwd()
user, hostname, shell env + socket
env filtered allowlist of safe vars only
history_tail last 200 lines of ~/.zsh_history or ~/.bash_history, with secrets redacted
terminal TERM_PROGRAM, version
multiplexer tmux/zellij session info if attached
git branch, HEAD, dirty file count, remote
claude_code project slot, count of conversation logs and memory files
bundle (with --bundle) compressed Claude Code project directory

Secret redaction

The tool scans history lines and env values against 11 patterns before writing:

  • GitHub tokens (ghp_*, gho_*, ghu_*, ghs_*, ghr_*)
  • Anthropic (sk-ant-api*)
  • OpenAI-style (sk-*)
  • AWS access keys (AKIA*, ASIA*)
  • DigitalOcean tokens (dop_v1_*, DO00*)
  • Twilio (SK[hex]{32}, AC[hex]{32})
  • Long base64-ish strings (≥40 chars)
  • JWTs (eyJ*.*.*)
  • PEM private key headers

Matches are replaced with [REDACTED] in the .lok output. The original history file on disk is untouched — you still need to rotate leaked credentials.

Env var names containing TOKEN, KEY, SECRET, PASSWORD, PASSWD, CREDENTIAL, AUTH, PRIVATE are dropped entirely.

Output

A single JSON file. Typical size: - No bundle: 5–10 KB - With --bundle: 1–5 MB (depends on Claude Code history depth)

Summary output

Captured: ghostty-session.lok (2351.7 KB)

Contents:
  cwd:          /Users/user/lokust-platform
  shell:        zsh
  terminal:     ghostty 1.3.1
  multiplexer:  none
  git:          main @ abc123def456 (0 dirty)
  claude code:  4 sessions, 10 memory files
  history:      200 commands (3 redacted)
  env:          11 vars (32 filtered)
  bundle:       claude-code-project embedded (2345.4 KB base64)

lokust-shell-restore

Restore a captured shell session on the local machine.

Usage

lokust-shell-restore <file.lok> [--target-dir PATH] [--no-shell]

Flags:

  • --target-dir PATH — restore to a different project directory than the one captured. The Claude Code slot name is rewritten to match.
  • --no-shell — print the banner and restore state, but do not exec a shell (useful for scripting or inspection).

What it does

  1. Extracts the --bundle payload (if present) into ~/.claude/projects/<slot>/. Any existing directory is backed up to <slot>.pre-restore.
  2. Prints a banner with cwd, git state, Claude Code summary, and the last 8 history commands.
  3. Sets LOKUST_RESTORED_FROM=<session-id> in the environment.
  4. chdir to the captured (or target) cwd.
  5. execvpe the user's shell as a login shell.

The shell inherits the restored env vars (except HOME, USER, SHELL, PATH which stay machine-local).

Cross-device restore

When the captured cwd doesn't exist on the target machine, pass --target-dir:

# Captured on: /Users/alice/code/lokust-platform
# Restoring on: /Users/bob/projects/lokust-platform
lokust-shell-restore alice.lok --target-dir /Users/bob/projects/lokust-platform

The Claude Code slot name (-Users-alice-code-lokust-platform) is rewritten to the target machine's equivalent (-Users-bob-projects-lokust-platform) during extraction, so Claude Code resumes the conversation when opened in the target directory.


lokust-tmux

Persistent shell sessions via tmux. Level-2 portability: the shell keeps running when you detach.

Subcommands

lokust-tmux new [name]               # create session
lokust-tmux ls                       # list
lokust-tmux attach <name>            # reattach
lokust-tmux export <name> [out.lok]  # snapshot (bundles Claude Code + scrollback)
lokust-tmux kill <name>              # destroy session

new

Creates a detached tmux session sized 200×50. Writes LOKUST_SESSION=<name> into its env.

$ lokust-tmux new myshell
Created tmux session: myshell
Attach: lokust-tmux attach myshell
Export: lokust-tmux export myshell

If no name is given, one of the form lokust-HHMMSS is generated.

ls

$ lokust-tmux ls
myshell: 1 windows (created Sun Apr 12 18:36:13 2026)

attach

lokust-tmux attach myshell

Ctrl-B d to detach without killing the session.

export

Runs lokust-shell-snapshot --bundle with the tmux session referenced, then injects the session's current pane scrollback (captured via tmux capture-pane) into the .lok as tmux_scrollback.

$ lokust-tmux export myshell
Captured: lokust-tmux-myshell-20260412-184325.lok (2347.3 KB)
  ...
  multiplexer:  {'kind': 'tmux', 'session': 'myshell'}
  bundle:       claude-code-project embedded
(scrollback embedded)

kill

lokust-tmux kill myshell

Where snapshots live

By default, .lok files are written to the current working directory with names like lokust-shell-YYYYMMDD-HHMMSS.lok. You can pass an explicit path to any command. Long-term storage is your choice — they're portable JSON files.