Thread System
Loom’s thread system provides persistent conversation history with bidirectional synchronization between local storage and the server. Every coding session is a thread that captures:- Complete message history (user, assistant, tool calls)
- Agent state (waiting, executing tools, error)
- Git context (branch, commits, remote URL)
- Workspace metadata
Architecture
Thread: Core data model (defined inloom-common-thread/src/model.rs)LocalThreadStore: XDG-compliant local storageSyncingThreadStore: Hybrid store with background syncThreadSyncClient: HTTP client for server communicationPendingSyncQueue: Offline-first sync queue
Thread Data Model
Thread Structure
Thread ID Format
Thread IDs use UUIDv7 (time-ordered) with aT- prefix:
- Sortable by creation time
- No collision risk (globally unique)
- Human-readable prefix
- Compatible with databases (indexed strings)
Message Types
- User
- Assistant
- Tool
Agent States
- Retry count (for error recovery)
- Last error message (if applicable)
- Pending tool calls (for
ExecutingTools)
Thread Visibility
Local Storage
XDG Directory
Threads are stored in:LocalThreadStore API
save_and_sync() blocks until server sync completes. Use for commands that exit immediately (e.g., loom share).Local Search
Fallback when server is unavailable:- Thread title
- Git branch name
- Git remote URL
- Commit SHAs (prefix match)
- Tags
- Message content (full text)
Server Synchronization
Sync Strategy
Loom uses offline-first synchronization:1
Save locally first
2
Queue for sync
3
Background sync
Spawned task processes queue:
4
Handle conflicts
Server returns latest version on conflict. Client merges or retries.
- Works offline (local-first)
- No blocking on network
- Automatic retry on failure
- Conflict detection via versioning
SyncingThreadStore
Sync API Endpoints
- Upsert Thread
- Fetch Thread
- List Threads
- Search Threads
- Thread ownership (via auth token)
- Version number (optimistic locking)
- Visibility rules
Git Integration
Loom automatically captures git state:Snapshot Workflow
- On thread creation
- After every tool execution
- On graceful shutdown (Ctrl+C, EOF)
Search by Git Metadata
Private Sessions
Create local-only sessions that never sync:is_private = truevisibility = Private
SyncingThreadStore skips sync for private threads:
- Sensitive codebases
- Offline development
- Personal experiments
Thread Lifecycle
1
Creation
2
User Input
3
LLM Response
4
Tool Execution
5
State Update
Resume Behavior
- Full conversation history
- Agent state (resumes from last checkpoint)
- Workspace context (warns if workspace changed)
- Git state (shows branch/commit changes)
Search Implementation
Server-Side Search
PostgreSQL full-text search:Local Search Fallback
Substring matching across all fields:Performance Optimizations
Lazy Loading
Thread summaries load minimal data. Full threads fetched on demand.
Background Sync
Non-blocking sync prevents UI lag. Errors retried automatically.
Local Caching
Recently accessed threads cached in memory (future enhancement).
Indexed Search
PostgreSQL GIN indexes for fast full-text queries.
Troubleshooting
Thread sync failed
Thread sync failed
Check network connectivity:Verify authentication:The thread is still saved locally. Sync retries automatically.
Thread not found
Thread not found
List all threads:Search by content:Check local storage:
Version conflict
Version conflict
Happens when thread modified on multiple devices simultaneously.The server returns HTTP 409. Client should:
- Fetch latest version from server
- Merge changes (manual or automatic)
- Retry with updated version
Search returns no results
Search returns no results
Try:
- Broader query terms
- Different keywords (branch name, repo URL)
- Local search if server is down