diff --git a/docs/features/session-persistence.md b/docs/features/session-persistence.md index 19e53c385..a790a117a 100644 --- a/docs/features/session-persistence.md +++ b/docs/features/session-persistence.md @@ -433,14 +433,26 @@ await client.deleteSession("user-123-task-456"); ## Automatic Cleanup: Idle Timeout -The CLI has a built-in 30-minute idle timeout. Sessions without activity are automatically cleaned up: +By default, sessions have **no idle timeout** and live indefinitely until explicitly disconnected or deleted. You can optionally configure a server-wide idle timeout via `CopilotClientOptions.sessionIdleTimeoutSeconds`: + +```typescript +const client = new CopilotClient({ + sessionIdleTimeoutSeconds: 30 * 60, // 30 minutes +}); +``` + +When a timeout is configured, sessions without activity for that duration are automatically cleaned up. The minimum value is 300 seconds (5 minutes). Set to `0` or omit to disable. + +> **Note:** This option only applies when the SDK spawns the runtime process. When connecting to an existing server via `cliUrl`, the server's own timeout configuration applies. ```mermaid flowchart LR - A["⚡ Last Activity"] --> B["⏳ 25 min
timeout_warning"] --> C["🧹 30 min
destroyed"] + A["⚡ Last Activity"] --> B["⏳ ~5 min before
timeout_warning"] --> C["🧹 Timeout
destroyed"] ``` -Listen for idle events to know when work completes: +Sessions with active work (running commands, background agents) are always protected from idle cleanup, regardless of the timeout setting. + +Listen for idle events to react to session inactivity: ```typescript session.on("session.idle", (event) => { diff --git a/nodejs/src/client.ts b/nodejs/src/client.ts index c5b84a6d4..fad4e7054 100644 --- a/nodejs/src/client.ts +++ b/nodejs/src/client.ts @@ -339,6 +339,7 @@ export class CopilotClient { // Default useLoggedInUser to false when githubToken is provided, otherwise true useLoggedInUser: options.useLoggedInUser ?? (options.githubToken ? false : true), telemetry: options.telemetry, + sessionIdleTimeoutSeconds: options.sessionIdleTimeoutSeconds ?? 0, }; } @@ -1385,6 +1386,16 @@ export class CopilotClient { args.push("--no-auto-login"); } + if ( + this.options.sessionIdleTimeoutSeconds !== undefined && + this.options.sessionIdleTimeoutSeconds > 0 + ) { + args.push( + "--session-idle-timeout", + this.options.sessionIdleTimeoutSeconds.toString() + ); + } + // Suppress debug/trace output that might pollute stdout const envWithoutNodeDebug = { ...this.options.env }; delete envWithoutNodeDebug.NODE_DEBUG; diff --git a/nodejs/src/types.ts b/nodejs/src/types.ts index 0c901f989..59cbffac9 100644 --- a/nodejs/src/types.ts +++ b/nodejs/src/types.ts @@ -182,6 +182,15 @@ export interface CopilotClientOptions { * instead of the server's default local filesystem storage. */ sessionFs?: SessionFsConfig; + + /** + * Server-wide idle timeout for sessions in seconds. + * Sessions without activity for this duration are automatically cleaned up. + * Set to 0 or omit to disable (sessions live indefinitely). + * Minimum value: 300 (5 minutes). + * @default undefined (disabled) + */ + sessionIdleTimeoutSeconds?: number; } /**