How Prime Agent's Daemon Protocol Handles Background Session Management

Prime Agent uses a long-running daemon process with a typed protocol (defined in daemon-protocol.ts) to manage interactive sessions that persist beyond client disconnects, supporting resident sessions, snapshot replay, and dynamic attach/resume operations.

The daemon protocol is the contract that enables Prime Agent to run background sessions independently of any connected client. This architecture allows AI coding sessions to survive network interruptions, IDE restarts, or complete client handoffs. The protocol is implemented across a suite of TypeScript files in packages/coding-agent/src/modes/daemon/ and governs everything from initial handshake to graceful shutdown.

Core Daemon Protocol Concepts for Session Management

Protocol Versioning and Capabilities

Every daemon-client interaction begins with capability negotiation. The protocol declares its identity through DAEMON_PROTOCOL_INFO (line 112 of daemon-protocol.ts), which includes the protocol name, version, and schema ID. This ensures version compatibility before any session operations begin.

Clients advertise their supported features via DAEMON_DEFAULT_CLIENT_CAPABILITIES and DAEMON_SUPPORTED_CLIENT_CAPABILITIES (lines 117-122). The daemon responds with DAEMON_DEFAULT_SERVER_CAPABILITIES (line 131), declaring features like snapshotting and session ownership that govern how background sessions behave.

Session Lifecycle Modes

The DaemonSessionLifecycle type (line 175) defines two critical modes:

  • "resident" — Sessions survive client disconnects and continue running in the background
  • "client_owned" — Sessions terminate automatically when the owning client disconnects

When a client connects, the daemon returns DaemonAttachResult (lines 285-307), containing sessionId, attachId, resumeCursor, and the sessionLifecycle designation. This metadata determines whether the session can be resumed later.

Snapshot and Replay Infrastructure

For resident sessions, the protocol defines DaemonSessionSnapshot, DaemonReplayInfo, and DaemonReplayStatus (lines 266-285). These types enable:

  • Periodic persistence of session transcripts
  • Full state restoration for new clients
  • Cursor-based replay positioning

The snapshot-transcript-cache.ts module handles the actual snapshot creation and storage operations.

Background Session Management Flow

Step 1: Daemon Initialization

The daemon process starts via daemon-launch.ts, binding to a Unix socket path. It immediately advertises DAEMON_PROTOCOL_VERSION = 7 (line 53) and DAEMON_SCHEMA_ID (line 64) from daemon-protocol.ts.

Environment propagation helpers collectDaemonClientEnv and collectDaemonLaunchEnv (lines 186-206) ensure API keys and other critical variables flow from launching client to daemon process via DAEMON_CLIENT_ENV_KEYS.

Step 2: Client Handshake and Attach

New clients use daemon-client.ts to establish communication. The handshake sequence:

  1. Client sends daemon_hello with its capabilities
  2. Daemon responds with DaemonAttachResult
  3. Client inspects sessionLifecycle to understand persistence guarantees

The attachId field supports multiple clients observing the same session simultaneously.

Step 3: Background Persistence for Resident Sessions

Resident sessions trigger automatic snapshot creation through snapshot-transcript-cache.ts. Each snapshot conforms to DaemonSessionSnapshot and captures:

  • Complete conversation transcript
  • Session metadata
  • Tool execution state

These snapshots enable true background operation—work continues even with zero connected clients.

Step 4: Resume and Dynamic Attachment

Later clients can attach to existing sessions using the attach capability. The protocol validates the resumeCursor against stored snapshots, then streams the transcript delta to bring the new client to current state.

The daemon-session-list.ts module maintains the in-memory catalog of active sessions available for attachment.

Step 5: Health Monitoring via Heartbeats

Client liveness detection relies on DaemonHeartbeat (re-exported from agent connection, line 146) and the heartbeat-catalog.ts implementation. Clients poll periodically; missed heartbeats trigger reconnection logic or daemon restart coordination via daemon-supervisor.ts.

Step 6: Graceful Shutdown Handling

When shut down, the daemon:

  • Marks sessions with DaemonSessionClosedReason = "shutdown"
  • Writes final snapshots for resident sessions
  • Sends daemon_shutdown_in_progress errors to attached clients

This ensures no background work is lost ungracefully.

Protocol Implementation Files

File Responsibility Key Exports
daemon-protocol.ts Message types, versioning, capability constants DAEMON_PROTOCOL_INFO, DaemonAttachResult, DaemonSessionLifecycle
daemon-mode.ts Socket handling, session creation, shutdown orchestration Daemon process entry point
daemon-supervisor.ts Multi-daemon coordination, worker recovery Process supervision logic
daemon-client.ts Client-side RPC implementation DaemonClient class with connect(), attach() methods
daemon-session-list.ts Active session registry In-memory session catalog
snapshot-transcript-cache.ts Periodic snapshot creation and replay Snapshot persistence and retrieval
heartbeat-catalog.ts Liveness monitoring Heartbeat message management

Practical Code Examples

Launching the Daemon

prime-agent --mode daemon --daemon-socket /tmp/prime-daemon.sock &

The daemon immediately advertises protocol version 7 and its schema ID for client negotiation.

Attaching to a Resident Session

import { DaemonClient } from "packages/coding-agent/src/modes/daemon/daemon-client.js";

const client = new DaemonClient("/tmp/prime-daemon.sock");
await client.connect();  // transmits daemon_hello

const attachResult = await client.attach({
  sessionId: "abc123",      // from previous DaemonAttachResult
  attachId: "client-42",
});

console.log(`Lifecycle: ${attachResult.sessionLifecycle}`);
console.log(`Resume cursor: ${attachResult.resumeCursor}`);

The attachResult contains all metadata needed for session continuity, including snapshot availability.

Triggering Manual Snapshot

import { DaemonClient } from ".../daemon-client.js";

await client.saveSnapshot({
  sessionId: "abc123",
  snapshot: {
    transcript: [...],
    metadata: { checkpoint: "pre-deployment" },
  },
});

Manual snapshots supplement automated periodic snapshots from snapshot-transcript-cache.ts.

Design Decisions in the Daemon Protocol

Type safety at the boundary — Every message in daemon-protocol.ts is fully typed, preventing version skew between client and daemon.

Explicit capability gating — Features like attach, resume, and snapshot replay must be declared in capability flags before use, avoiding runtime errors on unsupported configurations.

Environment isolation with selective propagation — Rather than inheriting all environment variables, the daemon receives only keys listed in DAEMON_CLIENT_ENV_KEYS, reducing secret exposure.

Summary

  • Daemon protocol versioning via DAEMON_PROTOCOL_INFO ensures compatible client-daemon communication
  • Dual lifecycle modes (resident vs client_owned) give explicit control over session persistence
  • Snapshot and replay infrastructure enables seamless client handoffs and crash recovery
  • Heartbeat monitoring maintains system health visibility across distributed components
  • Capability-based feature negotiation prevents misuse of advanced features like dynamic attachment

Frequently Asked Questions

How does Prime Agent handle client disconnections without losing work?

The daemon protocol distinguishes between resident and client_owned session lifecycles. Resident sessions continue executing in the daemon process after disconnect, with snapshot-transcript-cache.ts persisting state periodically. When a new client connects via daemon-client.ts, the attach() method retrieves the latest snapshot using resumeCursor from DaemonAttachResult, restoring full context.

What happens if the daemon crashes during a background session?

The daemon-supervisor.ts module coordinates recovery. On restart, the supervisor checks daemon-session-list.ts for sessions with persisted snapshots. For resident sessions with valid DaemonSessionSnapshot records, the daemon can replay from the last checkpoint. The DaemonReplayStatus type (lines 280-285 of daemon-protocol.ts) communicates replay progress to reconnecting clients.

Can multiple clients connect to the same background session simultaneously?

Yes, through the attach capability declared in DAEMON_SUPPORTED_CLIENT_CAPABILITIES. Each attachment receives a unique attachId in its DaemonAttachResult. The daemon broadcasts output to all attached clients while maintaining a single execution context. This enables collaborative debugging scenarios where multiple developers observe the same AI session.

How are API keys and secrets protected when the daemon outlives the launching client?

Environment propagation is strictly controlled via collectDaemonLaunchEnv and DAEMON_CLIENT_ENV_KEYS (lines 186-206). Only explicitly listed keys flow to the daemon process. The daemon stores no client credentials internally—sensitive state lives in the snapshot's encrypted transcript metadata, with access governed by filesystem permissions on the socket path and snapshot storage.

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 →