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.addAdditionalDir stored under additional/)
  • 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.ts coordinates all persistence operations
  • State serializes to JSON-Lines format in wire.jsonl within 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(), and delete() 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:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →