How to Enable Session Persistence in the GitHub Copilot SDK

Enable session persistence in the GitHub Copilot SDK by supplying a sessionFs configuration object when instantiating CopilotClient, specifying sessionStatePath, initialCwd, and conventions to automatically persist events, checkpoints, and generated files across sessions.

The GitHub Copilot SDK maintains state across tool invocations through its Session FS abstraction. When you enable session persistence, the SDK captures every event, checkpoint, and generated file to a durable location using the sessionFs provider system, allowing you to resume work or audit previous interactions. This guide explains the configuration options and source code implementation used to enable session persistence in the github/copilot-sdk repository.

Understanding the Session FS Architecture

The SDK implements persistence through a JSON-RPC handler that intercepts filesystem operations under the sessionFs.* namespace. According to the source code in nodejs/src/client.ts, the architecture follows four distinct steps:

  1. Handler creation: The SDK creates a SessionFsHandler that implements RPC methods like sessionFs.writeFile and sessionFs.readFile
  2. Provider wrapping: Uses createSessionFsAdapter (source: nodejs/src/sessionFsProvider.ts lines 19-33) to wrap your SessionFsProvider into a compliant handler
  3. Connection registration: Attaches the handler to the JSON-RPC connection during CopilotClient initialization (line 828 of nodejs/src/client.ts)
  4. State persistence: Automatically writes session events to <sessionStatePath>/events.jsonl, checkpoints to checkpoints/, and temporary files to temp/

Key Source Files

Configuring Session Persistence

To enable session persistence with the built-in filesystem provider, pass a sessionFs object to the CopilotClient constructor.

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

const client = new CopilotClient({
  sessionFs: {
    sessionStatePath: '/tmp/copilot-session',
    initialCwd: '/tmp/copilot-session',
    conventions: 'posix',
  },
});

The three required parameters are:

  • sessionStatePath: The root directory where the SDK stores events.jsonl, checkpoints, and temporary files
  • initialCwd: The working directory that the session recognizes as its current working directory
  • conventions: The path style to use, either 'posix' or 'windows'

Enabling SQLite Persistence

For applications requiring structured query capabilities, enable the SQLite capability in your configuration.

const client = new CopilotClient({
  sessionFs: {
    sessionStatePath: '/tmp/copilot-session',
    initialCwd: '/tmp/copilot-session',
    conventions: 'posix',
    capabilities: { sqlite: true },
  },
});

// Execute queries against the session database
await client.rpc.sessionFs.sqliteQuery({
  queryType: 'exec',
  query: 'CREATE TABLE logs(id INTEGER PRIMARY KEY, event TEXT);',
});

When enabled, the SDK exposes sessionFs.sqliteQuery methods as defined in nodejs/src/generated/rpc.ts. The end-to-end tests in nodejs/test/e2e/session_fs_sqlite.e2e.test.ts demonstrate this functionality.

Implementing a Custom SessionFsProvider

For cloud storage or custom backends, implement the SessionFsProvider interface and pass it through the adapter.

import { CopilotClient, SessionFsProvider } from '@github/copilot-sdk/nodejs';

const cloudProvider: SessionFsProvider = {
  async readFile(path) { /* fetch from cloud storage */ },
  async writeFile(path, content) { /* upload to cloud storage */ },
  async appendFile(path, content) { /* ... */ },
  async exists(path) { /* ... */ },
  async stat(path) { /* ... */ },
  async mkdir(path, recursive) { /* ... */ },
  async readdir(path) { /* ... */ },
  async readdirWithTypes(path) { /* ... */ },
  async rm(path, recursive, force) { /* ... */ },
  async rename(src, dest) { /* ... */ },
};

const client = new CopilotClient({
  sessionFs: {
    sessionStatePath: '/tmp/copilot-session',
    initialCwd: '/tmp/copilot-session',
    conventions: 'posix',
  },
});

The createSessionFsAdapter function (lines 14-33 of nodejs/src/sessionFsProvider.ts) automatically wraps your provider, converting thrown errors into SessionFsError objects for RPC compatibility. You can also pass a custom adapter directly via the sessionFsAdapter option if you need direct control over the wrapping process.

Summary

  • Session persistence requires a sessionFs configuration object in CopilotClient options as implemented in nodejs/src/client.ts
  • State storage uses sessionStatePath to write events to events.jsonl, checkpoints to checkpoints/, and temp files to temp/
  • Required fields include sessionStatePath, initialCwd, and conventions (path style)
  • SQLite support is optional via capabilities: { sqlite: true } and exposes sessionFs.sqliteQuery methods
  • Custom providers implement the SessionFsProvider interface and are automatically wrapped by createSessionFsAdapter in sessionFsProvider.ts

Frequently Asked Questions

Where does the GitHub Copilot SDK store session events?

The SDK writes all session events to <sessionStatePath>/events.jsonl as newline-delimited JSON. Checkpoints are stored under <sessionStatePath>/checkpoints/ and temporary files under <sessionStatePath>/temp/, as verified in nodejs/test/e2e/session_fs.e2e.test.ts.

Can I use cloud storage instead of the local filesystem?

Yes. Implement the SessionFsProvider interface (defined in nodejs/src/sessionFsProvider.ts lines 54-96) with methods like readFile, writeFile, and mkdir. The SDK wraps your implementation with createSessionFsAdapter to handle RPC serialization and error conversion, allowing you to store session state in S3, GCS, or any remote backend.

Is SQLite support required for session persistence?

No. SQLite is an optional capability enabled by setting capabilities: { sqlite: true } in the sessionFs configuration. When disabled, the SDK still persists events and files to disk using the standard filesystem methods, but sessionFs.sqliteQuery RPC methods will be unavailable.

How does the SDK validate session persistence configuration?

The CopilotClient constructor validates the sessionFs object during initialization (lines 801-809 of nodejs/src/client.ts). It checks for required fields like conventions and sessionStatePath, then registers the handler on line 828. If validation fails, the constructor throws before establishing the JSON-RPC connection.

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 →