How to Save and Resume Copilot SDK Session State

The Copilot SDK automatically persists a session's conversational history, plan, and workspace files when session.disconnect() is called, and restores that exact state later through client.resumeSession(sessionId, config) using the original session ID.

The GitHub Copilot SDK is designed with built-in durability that lets your agent pick up conversations across process restarts, crashes, or scaled deployments. When you need to save and resume Copilot SDK session state, the runtime manages the persistence layer for you—flushing in-memory data to disk and rehydrating it on demand. Below is a source-level breakdown of the mechanism, configuration options, and production-ready code patterns found in the SDK.

How Session Persistence Works

The persistence mechanism operates in two distinct layers implemented in the TypeScript SDK.

  • SDK-managed shutdown — Calling session.disconnect() triggers the runtime to write the session's in-memory data to an on-disk store. This implementation lives in nodejs/src/session.ts, where the disconnect method executes the flush operation. The resulting workspace is accessible through the workspacePath getter exposed by the same file.

  • SDK-managed restart — Calling client.resumeSession(sessionId, config) reads the stored state from disk, re-instantiates a CopilotSession, and re-attaches all handlers including tools, permission hooks, and UI callbacks. This logic is implemented in nodejs/src/client.ts. The method registers the session before sending the resume RPC so that runtime events such as session.start are not missed.

Where Session State Is Stored

By default, the runtime uses COPILOT_HOME, which resolves to ~/.copilot unless overridden.

You can redirect storage to a custom path in two ways:

  • baseDirectory — Passed directly to the CopilotClient constructor. This makes the runtime write all session files under a single root you control.
  • sessionFs — A SessionFsConfig object that registers a custom filesystem provider via the sessionFs.setProvider call in nodejs/src/client.ts. This gives you fine-grained control over every session-scoped read and write operation.

Step-by-Step: Save and Resume a Session

Follow these steps to reliably persist a session and restore it later.

1. Create a Client With Persistent Storage

Configure the client with an optional custom base directory or a full SessionFsConfig:

import { CopilotClient } from "@github/copilot-sdk";

const client = new CopilotClient({
  // Optional: redirect the default ~/.copilot root
  baseDirectory: "/data/copilot-home",
  // Optional: full provider config for fine-grained control
  sessionFs: {
    initialCwd: process.cwd(),
    sessionStatePath: "/data/copilot-home/session-state",
    conventions: "posix",
  },
});

Setting baseDirectory redirects the default runtime store. Providing sessionFs registers a custom filesystem provider that the runtime invokes for all session I/O.

2. Create a Session and Interact

Spawn a new session and run your conversation as usual:

const session = await client.createSession({
  model: "gpt-4",
  onPermissionRequest: approveAll,
});

await session.sendAndWait({ prompt: "Explain the design of the SDK." });

3. Disconnect to Flush State to Disk

Call disconnect() to trigger the persistence layer:

await session.disconnect();

After this call returns, the session’s workspace and conversation state exist on disk at the path exposed by session.workspacePath.

4. Resume the Session by ID

Store the sessionId value in a database, environment variable, or cache. Later, re-attach to the same conversation:

const resumed = await client.resumeSession(session.sessionId, {
  onPermissionRequest: approveAll,
});

await resumed.sendAndWait({ prompt: "Continue where we left off." });

You may supply new handlers, tools, or callbacks during resume; they replace the originals attached at creation time.

Complete Example

Here is a full, runnable script that ties the steps together using a custom storage path and infinite session mode:

import { CopilotClient, approveAll } from "@github/copilot-sdk";

async function main() {
  const client = new CopilotClient({
    baseDirectory: "/var/copilot-data",
    sessionFs: {
      initialCwd: process.cwd(),
      sessionStatePath: "/var/copilot-data/sessions",
      conventions: "posix",
    },
  });

  const session = await client.createSession({
    model: "gpt-4",
    onPermissionRequest: approveAll,
    infiniteSessions: { enabled: true },
  });

  await session.sendAndWait({ prompt: "Write a TypeScript utility that parses CSV." });

  await session.disconnect();

  console.log("Session saved, ID:", session.sessionId);
  console.log("Workspace on disk:", session.workspacePath);

  const resumed = await client.resumeSession(session.sessionId, {
    onPermissionRequest: approveAll,
  });

  await resumed.sendAndWait({ prompt: "Add unit tests for the CSV utility." });
}

main().catch(console.error);

This creates a workspace under /var/copilot-data/sessions/<sessionId>/, safely stores all files and the conversation log on disconnect, and restores the exact session when resumeSession is called.

Enable Crash-Resistant Sessions With Infinite Session Mode

If you enable infinite sessions by passing infiniteSessions: { enabled: true } in the SessionConfig, the runtime continuously writes checkpoint data to workspacePath/checkpoints/. This provides automatic crash recovery without requiring an explicit call to disconnect. You still resume the session later using client.resumeSession(...).

Implement a Custom Session Filesystem for Advanced Workloads

When you need a non-standard directory layout—such as per-tenant isolation on a shared server—implement the SessionFsProvider interface and pass it via the sessionFs option or a createSessionFsProvider callback.

The SDK bridges your provider to the runtime by calling createSessionFsAdapter in nodejs/src/sessionFsProvider.ts. Once registered, the runtime calls your readFile, writeFile, and other methods for all session-scoped I/O. Because the runtime uses your provider for both writing and reading, the exact same files are available when you later resume.

Summary

  • Call session.disconnect() to flush a session's in-memory history, plan, and workspace files to disk, as implemented in nodejs/src/session.ts.
  • Reconnect later with client.resumeSession(sessionId, config), defined in nodejs/src/client.ts, which restores the full state and re-attaches handlers.
  • Default storage lives under ~/.copilot (COPILOT_HOME), but you can override it with baseDirectory or a custom SessionFsConfig.
  • Use infinite session mode for continuous checkpointing and crash resilience.
  • For server or multi-tenant scenarios, implement SessionFsProvider to control exactly where session files live.

Frequently Asked Questions

Does the Copilot SDK auto-save session state when my process exits?

Not automatically on exit alone. The SDK writes state when session.disconnect() is called or when the session is disposed via await using. For crash protection without manual calls, enable infiniteSessions: { enabled: true } so the runtime continuously checkpoints to disk.

Can I resume a session from a different machine or container?

Yes, as long as the new process can access the same on-disk store. Use the same baseDirectory or sessionFs configuration when constructing CopilotClient, then call resumeSession(sessionId) with the original ID. The runtime rehydrates the conversation from the shared path.

What is the difference between baseDirectory and sessionFs?

baseDirectory is a convenience option that redirects the default ~/.copilot root to another path. sessionFs is a full SessionFsConfig that lets you register a custom filesystem provider, giving you programmatic control over every file operation the runtime performs during the session lifecycle.

Where can I find the on-disk workspace path for a specific session?

After creating or resuming a session, read the workspacePath getter on the CopilotSession object. This property is defined in nodejs/src/session.ts and returns the absolute path to the session's files on disk.

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 →