How Session State is Persisted and Managed Across Kimi-Code Restarts
Kimi-Code persists session state using a JSON-Lines log file (wire.jsonl) stored in a per-session directory, which SessionStore replays on startup to rebuild the full transcript and resume execution.
The MoonshotAI/kimi-code repository implements durable session persistence through a filesystem-backed architecture. Every conversation turn, tool invocation, and metadata update is appended to a local log, enabling seamless recovery after server or CLI restarts without losing context.
Core Persistence Architecture
The SessionStore Component
At the heart of kimi-code's durability layer sits the SessionStore class in packages/agent-core/src/session/store/session-store.ts. This component manages the lifecycle of session data, coordinating between in-memory state and disk storage.
When initialized, the constructor (lines 380–420) establishes a dedicated directory under the kimi-code data root:
~/.kimi-code/server/instances/<instance>/sessions/<session-id>/
The store instantiates a FileSystemAgentRecordPersistence handler from packages/agent-core/src/session/store/file-system-persistence.ts to manage low-level I/O operations including read(), append(), rewrite(), and flush().
The wire.jsonl Format
All state mutations serialize to a JSON-Lines file named wire.jsonl. Each line represents an AgentRecord containing transcript operations, plan revisions, or configuration updates. This append-only structure ensures crash safety and enables efficient streaming replays.
The format captures:
- Transcript operations (turns, tool frames, plan updates)
- Session metadata (title, working directory, custom fields)
- Plan revision references (pointers to markdown files under the
plan/subdirectory) - Workspace attachments (files added via
session.addAdditionalDirstored underadditional/) - MCP and user configuration ( reapplied during rebuild)
Writing Session State to Disk
Real-Time Record Appending
During active sessions, the engine emits transcript operations that SessionStore immediately persists. At lines 891–893 of session-store.ts, the implementation appends each record synchronously:
persistence.append(record);
await persistence.flush();
This guarantees that every tool call and agent response survives a sudden process termination.
Durability Guarantees
The FileSystemAgentRecordPersistence implementation ensures data integrity through explicit flushing. Unlike buffered writes that risk data loss on crash, kimi-code forces filesystem synchronization after each append operation, trading marginal write latency for reliability.
Recovering State After Restart
Cold Rebuild Process
When the kimi-code server boots, SessionStore.read() (lines 637–701) executes a cold rebuild. The method iterates through the session's wire.jsonl, reconstructing the transcript object and reinitializing per-agent sequence number watermarks.
This process transforms the append-only log back into a functional in-memory state managed by the @moonshot-ai/transcript layer, making sessions available to the SDK and UI without manual intervention.
In-Memory Journal for Live Streams
To optimize WebSocket performance without sacrificing durability, packages/kap-server/src/transport/ws/v1/sessionEventJournal.ts maintains a bounded in-memory journal. This mirrors the sequence numbers persisted to disk, enabling fast event replay for reconnecting clients while avoiding redundant filesystem reads.
Resuming Sessions via the SDK
The Node SDK exposes session persistence through intuitive methods. Below are practical implementations for common workflows.
Creating a Persisted Session
By default, sessions enable persistence automatically:
import { KimiHarness } from '@moonshot-ai/node-sdk';
const client = new KimiHarness({ /* auth config */ });
async function start() {
const session = await client.createSession({
title: 'Data Analysis',
persist: true, // defaults to true
});
console.log('Session ID:', session.id);
}
start();
Source: packages/node-sdk/src/session.ts (line 174)
Attaching Files with Persistence
Workspace attachments survive restarts when persisted:
import { join } from 'path';
import { readFileSync } from 'fs';
async function attachFile(sessionId: string) {
const content = readFileSync('data/input.txt');
await client.session.addAdditionalDir(sessionId, {
path: join('/tmp', 'input.txt'),
persist: true, // writes to session folder
});
}
Source: packages/node-sdk/src/rpc.ts (line 377)
Resuming After Server Restart
Recover an existing session using the resume API:
async function resume() {
const resumed = await client.session.resume({
id: 'session-abc123',
includePersistedSubagents: true,
});
console.log('Resumed title:', resumed.title);
// Transcript contains all prior turns
}
resume();
Source: packages/node-sdk/src/kimi-harness.ts (lines 139–148)
Deleting Persisted State
Remove both memory and disk artifacts:
await client.session.delete('session-abc123');
Source: packages/agent-core/src/tools/cron/session-store.ts (line 44)
What Gets Persisted (and What Doesn't)
Persisted to wire.jsonl:
- Engine-generated transcript operations
- Tool call frames and responses
- Plan revision markers
- Session metadata and configuration
- Additional directory references
Not persisted:
- UI-specific state (scroll positions, panel layouts)
- Transient client-side caches
- Uncommitted in-memory buffers
This selective approach minimizes disk footprint while preserving complete logical state for session continuity.
Summary
- SessionStore in
packages/agent-core/src/session/store/session-store.tscoordinates all persistence operations - State serializes to JSON-Lines format in
wire.jsonlwithin per-session directories - Synchronous flushing after each append ensures durability against crashes
- Cold rebuild logic replays logs on startup to reconstruct transcripts
- The Node SDK provides
createSession(),resume(), anddelete()methods for lifecycle management - Only engine events persist; UI state remains client-side
Frequently Asked Questions
Where is kimi-code session data stored on disk?
Session data resides in ~/.kimi-code/server/instances/<instance>/sessions/<session-id>/, specifically within a wire.jsonl file containing the JSON-Lines log. The SessionStore constructor creates this hierarchy during session initialization.
Does kimi-code persist UI state like scroll positions?
No. The persistence layer intentionally excludes UI-specific state such as scroll positions or panel layouts. Only engine-generated events—transcript operations, tool calls, and metadata—serialize to disk, keeping the log focused on execution context rather than interface state.
How does the SDK resume a session after server restart?
The SDK calls client.session.resume() with the session ID, which triggers the server to invoke SessionStore.read(). This method replays the wire.jsonl log, rebuilds the transcript via @moonshot-ai/transcript, and returns a fully rehydrated session object including all prior conversation history.
Is session persistence enabled by default?
Yes. When creating sessions through client.createSession(), the persist parameter defaults to true. You must explicitly set persist: false to create ephemeral sessions that exist only in memory.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →