/compact to reduce size and /rewind to go back to earlier points.Session Commands
All session management commands start with/session.
/session save <name>
/session load <name>
/session attach <name>
/session detach
/session status
/session list
/session delete <name>
/session new (or /newsession)
/newsession: it also drops any session binding and rotates the shared hub thread, so no backlog from the old conversation leaks into the new one./session fork <new-name>
Automatic saving on exit
You don’t have to remember/session save: when the interactive REPL exits, the conversation is auto-saved under a reserved autosave-YYYYMMDD-HHMMSS name. Trivial sessions (fewer than 2 non-system messages) are skipped, and one-shot -p runs never autosave. Gated by CHATCLI_SESSION_AUTOSAVE (on by default, shown in /config session). Autosaved conversations are fully searchable and readable via @session.
MCP sessions autosave too: the MCP/ACP server mirrors each live conversation to a rolling mcp-<session> file after every turn (both the full-pipeline and plain paths), and manage_session clear saves one last time before discarding. An explicit CHATCLI_MCP_SESSION_AUTOSAVE always wins; unset, it follows the global CHATCLI_SESSION_AUTOSAVE gate — on by default. Retention for both surfaces is covered under Automatic Cleanup below.
Cross-surface continuity
A named session is ChatCLI’s durable continuity layer across surfaces: the interactive REPL, the MCP server (chatcli mcp-server), the ACP server (chatcli acp) and the Chat Gateway all read and write the same session file. Start on the terminal, continue in the IDE, finish on WhatsApp — same conversation.
While a named session is active (after /session save, /session load or /session attach), the binding works in both directions on every turn:
- Write-through — each completed turn is written to the session file immediately (atomic write: temp file + rename, so there are never torn files).
- Adoption — before each turn, writes made by other surfaces (MCP/ACP server, gateway daemon, another terminal) since the last sync are adopted: when the file is newer, it replaces the in-memory history wholesale (last-writer-wins).
autosave-, mcp- prefixes) are rolling mirrors owned by the autosave paths — they never become live bindings.Where Sessions Are Stored
Sessions are saved as JSON files in a per-user store — the same store every surface (REPL, MCP/ACP server, gateway daemon) reads and writes:/session save debug-api creates the file:
SessionManager is the internal component responsible for all session file I/O. It handles read/write errors (permissions, full disk, malformed JSON) and displays clear messages if something fails./compact.
/session list to see them all.Data Format (v2)
Session files use the v2 format, defined by theSessionData struct in the models package. The JSON structure is:
Message Fields
Format Evolution
- v1 (older versions): Maintained separate histories per mode —
chat_history,agent_history, andcoder_historyeach with their own messages. - v2 (current version): Uses a unified history. The
chat_historyfield contains all messages from all modes. Theagent_historyandcoder_historyfields exist for compatibility but are empty in new sessions.
Unified History and Sessions
ChatCLI uses a single message array for all interaction modes. This means:- When saving a session, the entire unified history is serialized — including messages from chat, agent, and coder mode.
- System messages, tool call results, and compacted summaries are all preserved in the file.
- When loading a session, the current history is completely replaced by the loaded session’s history.
Interaction with Other Systems
Sessions interact with several other ChatCLI subsystems. Here is how each one behaves:Compaction (/compact)
The /compact command reduces history size by creating summaries of older messages. If you save a session after compacting, the resulting file will be significantly smaller, as it contains summaries instead of the original messages.
Rewind (/rewind)
The checkpoints used by /rewind exist only in memory during the current run. They are not saved in the session file. When loading a session, you will not have rewind points available until you create new ones during the conversation.
Bootstrap (SOUL.md, etc.)
Bootstrap files are not part of the session. They are loaded automatically on every ChatCLI startup, regardless of which session is active. This ensures that the AI’s base behavior is always consistent.Memory (/memory)
Memory is global — it is not tied to any specific session. Data saved with /memory save is available across all sessions and survives ChatCLI restarts.
Context (/context attach)
Contexts attached via /context attach are not saved in the session file. When loading a session, you need to re-attach the necessary contexts manually.
Auto-Save and Persistence
Besides the explicit/session save, persistence has two automatic layers:
- Bound named session — after
/session save,/session loador/session attach, every turn is written through to the session file (see Cross-surface continuity; gated byCHATCLI_SESSION_WRITETHROUGH, on by default). - Exit autosave — an unbound conversation is still saved as
autosave-YYYYMMDD-HHMMSSwhen the interactive REPL exits (see Automatic saving on exit; gated byCHATCLI_SESSION_AUTOSAVE, on by default).
The .chatcli_history File (Don’t Confuse)
ChatCLI maintains a separate file called .chatcli_history that stores the command input history (similar to ~/.bash_history). This file:
- Contains only the text you typed at the prompt, not the AI’s responses
- Is controlled by the
HISTORY_FILEandHISTORY_MAX_SIZEenvironment variables - Has no relation to session files (
~/.chatcli/sessions/*.json)
Recommended Workflow
To get the most out of the session system, follow these practices:Name sessions after the task
fix-auth-bug, refactor-api, docs-v2, debug-memory-leak.Compact before saving
/compact before /session save to reduce file size and keep only the essential information.Start clean before switching sessions
/session new before loading another session. This ensures the previous context doesn’t interfere.Switch between tasks freely
Session Encryption
Session files can be encrypted at rest using AES-256-GCM to protect sensitive conversation data:Automatic Cleanup
ChatCLI applies a bounded lifecycle to machine-created sessions on startup (REPL and MCP/ACP server alike). The core rule: sessions you named are never deleted automatically — only theautosave- and mcp- prefixed files ChatCLI creates on its own are subject to retention.
Name Validation
Session names are validated with a strict regex to prevent path traversal and problematic characters:- Allowed characters: letters (a-z, A-Z), numbers (0-9), hyphens (
-), underscores (_), and dots (.) - Length: 1 to 128 characters
- Forbidden: spaces, slashes, special characters,
..sequences
Frequently Asked Questions
Is there a size limit for sessions?
Is there a size limit for sessions?
HISTORY_MAX_SIZE variable (default: 100MB), but in practice sessions rarely exceed a few megabytes. If the history is too large, use /compact before saving to significantly reduce the size.Can I manually edit the session JSON file?
Can I manually edit the session JSON file?
version field).What happens if I load a session from an older version?
What happens if I load a session from an older version?
Can I have sessions with the same name in different directories?
Can I have sessions with the same name in different directories?
~/.chatcli/sessions, so the same names are visible from any directory and any surface (REPL, MCP/ACP server, gateway). That shared namespace is exactly what makes cross-surface continuity work; use task-specific names (projeto-a-debug, projeto-b-debug) to keep projects apart.