Skip to main content
Craft Agents provides a powerful session management system that persists all your conversations to disk, making them searchable, recoverable, and organized. Each session is stored in a human-readable format with automatic naming, metadata tracking, and efficient persistence.

Core Concepts

Sessions in Craft Agents are workspace-scoped conversations that store:

Conversation Data

All messages, tool calls, and agent responses in JSONL format

Metadata

Names, labels, statuses, flags, and timestamps

Attachments

File uploads, plans, and downloaded resources

Token Usage

Input/output tokens, costs, and cache statistics

Storage Structure

Sessions are stored at {workspaceRootPath}/sessions/{id}/ with the following structure:
sessions/
  260304-swift-river/        # Human-readable session ID
    session.jsonl            # Main data file (header + messages)
    attachments/             # User-uploaded files
    plans/                   # Safe Mode plan files
    data/                    # Transform tool output
    long_responses/          # Summarized tool results
    downloads/               # API-downloaded resources
The JSONL format stores the session header on line 1 (for fast list loading) and one message per line thereafter.

Session Identifiers

Human-Readable IDs

Craft Agents generates memorable session IDs in the format:
YYMMDD-adjective-noun
Examples:
  • 260304-swift-river
  • 260305-bright-forest
  • 260305-bright-forest-2 (collision handling)
1

Date Prefix

YYMMDD format makes sessions time-sortable
2

Random Words

~20,000 unique combinations per day from curated word lists
3

Collision Handling

Numeric suffix added if the base ID already exists

Code Example

packages/shared/src/sessions/slug-generator.ts
export function generateUniqueSessionId(
  existingIds: Set<string> | string[],
  date: Date = new Date()
): string {
  const existingSet = existingIds instanceof Set ? existingIds : new Set(existingIds);
  const datePrefix = generateDatePrefix(date);

  // Try up to 100 times to find a unique slug
  for (let attempt = 0; attempt < 100; attempt++) {
    const slug = generateHumanSlug();
    const baseId = `${datePrefix}-${slug}`;

    if (!existingSet.has(baseId)) {
      return baseId;
    }
  }
}

Session Persistence

Debounced Async Queue

Craft Agents uses a sophisticated persistence queue to avoid blocking the UI during saves:
Automatic Debouncing: Multiple rapid changes are coalesced into a single write (500ms window)Async I/O: All writes use Node.js async file operations to prevent main thread blockingPer-Session Serialization: Writes are serialized per session to prevent race conditions on .tmp filesAtomic Writes: Write to .tmp file, then rename to prevent corruption on crash
Always call sessionPersistenceQueue.flushAll() during app shutdown to ensure no data loss.

JSONL Format

Sessions are stored in JSONL (JSON Lines) format for efficient streaming and fast list views: Line 1: Session Header
{
  "id": "260304-swift-river",
  "workspaceRootPath": "~/.craft-agent/workspaces/default",
  "createdAt": 1709568000000,
  "lastUsedAt": 1709571600000,
  "name": "Build API docs",
  "sessionStatus": "in-progress",
  "labels": ["bug", "priority::2"],
  "messageCount": 12,
  "preview": "Help me refactor the authentication module",
  "tokenUsage": { "totalTokens": 15420, "costUsd": 0.42 }
}
Lines 2+: Messages
{"role":"user","content":"Help me refactor the authentication module"}
{"role":"assistant","content":"I'll analyze the current code..."}
The header includes pre-computed fields (message count, preview, token usage) so the UI can render session lists without parsing all messages.

Session Metadata

Tracked Fields

FieldTypeDescription
idstringUnique session identifier
namestring?Optional user-defined name
createdAtnumberUnix timestamp (milliseconds)
lastUsedAtnumberLast access time (any activity)
lastMessageAtnumber?Last meaningful message (for date grouping)
sessionStatusstringCurrent status (todo/in-progress/done/etc)
labelsstring[]Applied labels (“bug”, “priority::3”)
isFlaggedboolean?Whether session is flagged
isArchivedboolean?Whether session is archived
hasUnreadboolean?Whether session has unread messages
permissionModestring?Permission mode (safe/ask/allow-all)
modelstring?LLM model override
workingDirectorystring?Current working directory

Code Example

packages/shared/src/sessions/storage.ts
export async function updateSessionMetadata(
  workspaceRootPath: string,
  sessionId: string,
  updates: Partial<SessionConfig>
): Promise<void> {
  const session = loadSession(workspaceRootPath, sessionId);
  if (!session) return;

  if (updates.isFlagged !== undefined) session.isFlagged = updates.isFlagged;
  if (updates.name !== undefined) session.name = updates.name;
  if (updates.sessionStatus !== undefined) session.sessionStatus = updates.sessionStatus;
  if (updates.labels !== undefined) session.labels = updates.labels;

  await saveSession(session);
}

Listing Sessions

The storage layer provides filtered views for different UI contexts:

Active Sessions

listActiveSessions(workspaceRootPath)
// Returns non-archived sessions

Inbox Sessions

listInboxSessions(workspaceRootPath)
// Returns sessions with 'open' status

Completed Sessions

listCompletedSessions(workspaceRootPath)
// Returns sessions with 'closed' status

Archived Sessions

listArchivedSessions(workspaceRootPath)
// Returns archived sessions only

Performance Optimization

The session system is designed for workspaces with thousands of sessions:
1

Fast List Loading

Only reads the first line (header) of each JSONL file
2

Pre-Computed Fields

Message count, preview, and token usage stored in header
3

Lazy Message Loading

Full conversation loaded only when viewing a session
4

Debounced Persistence

Rapid changes coalesced into single disk write

Session Lifecycle

UI Features

Craft Agents provides several UI features to enhance your session experience:

Multi-File Diff Viewer

VS Code-style window for viewing all file changes in a turn. Shows side-by-side diffs of all modifications made by the agent.

Background Tasks

Run long-running operations with progress tracking. Sessions continue working while you focus on other tasks.

Real-Time Tool Visualization

See tool calls as they execute with status indicators and results.

Streaming Responses

Messages appear in real-time as the agent generates them, with syntax highlighting for code blocks.
Background tasks appear in the session list with a progress indicator. Click to view details or wait for completion notification.

Next Steps

Inbox & Archive

Learn about flagging and workflow navigation

Status System

Understand the dynamic status system

Labels

Organize sessions with hierarchical labels

Build docs developers (and LLMs) love