@github/copilot-sdk 0.1.31-unstable.0 → 0.1.32

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -52,10 +52,17 @@ await session.send({ prompt: "What is 2+2?" });
52
52
  await done;
53
53
 
54
54
  // Clean up
55
- await session.destroy();
55
+ await session.disconnect();
56
56
  await client.stop();
57
57
  ```
58
58
 
59
+ Sessions also support `Symbol.asyncDispose` for use with [`await using`](https://github.com/tc39/proposal-explicit-resource-management) (TypeScript 5.2+/Node.js 18.0+):
60
+
61
+ ```typescript
62
+ await using session = await client.createSession({ model: "gpt-5" });
63
+ // session is automatically disconnected when leaving scope
64
+ ```
65
+
59
66
  ## API Reference
60
67
 
61
68
  ### CopilotClient
@@ -265,9 +272,13 @@ Abort the currently processing message in this session.
265
272
 
266
273
  Get all events/messages from this session.
267
274
 
268
- ##### `destroy(): Promise<void>`
275
+ ##### `disconnect(): Promise<void>`
276
+
277
+ Disconnect the session and free resources. Session data on disk is preserved for later resumption.
278
+
279
+ ##### `destroy(): Promise<void>` *(deprecated)*
269
280
 
270
- Destroy the session and free resources.
281
+ Deprecated use `disconnect()` instead.
271
282
 
272
283
  ---
273
284
 
package/dist/client.d.ts CHANGED
@@ -19,6 +19,7 @@ export declare class CopilotClient {
19
19
  private typedLifecycleHandlers;
20
20
  private _rpc;
21
21
  private processExitPromise;
22
+ private negotiatedProtocolVersion;
22
23
  /**
23
24
  * Typed server-scoped RPC methods.
24
25
  * @throws Error if the client is not connected
@@ -74,10 +75,14 @@ export declare class CopilotClient {
74
75
  * Stops the CLI server and closes all active sessions.
75
76
  *
76
77
  * This method performs graceful cleanup:
77
- * 1. Destroys all active sessions with retry logic
78
+ * 1. Closes all active sessions (releases in-memory resources)
78
79
  * 2. Closes the JSON-RPC connection
79
80
  * 3. Terminates the CLI server process (if spawned by this client)
80
81
  *
82
+ * Note: session data on disk is preserved, so sessions can be resumed later.
83
+ * To permanently remove session data before stopping, call
84
+ * {@link deleteSession} for each session first.
85
+ *
81
86
  * @returns A promise that resolves with an array of errors encountered during cleanup.
82
87
  * An empty array indicates all cleanup succeeded.
83
88
  *
@@ -220,7 +225,8 @@ export declare class CopilotClient {
220
225
  */
221
226
  listModels(): Promise<ModelInfo[]>;
222
227
  /**
223
- * Verify that the server's protocol version matches the SDK's expected version
228
+ * Verify that the server's protocol version is within the supported range
229
+ * and store the negotiated version.
224
230
  */
225
231
  private verifyProtocolVersion;
226
232
  /**
@@ -242,10 +248,12 @@ export declare class CopilotClient {
242
248
  */
243
249
  getLastSessionId(): Promise<string | undefined>;
244
250
  /**
245
- * Deletes a session and its data from disk.
251
+ * Permanently deletes a session and all its data from disk, including
252
+ * conversation history, planning state, and artifacts.
246
253
  *
247
- * This permanently removes the session and all its conversation history.
248
- * The session cannot be resumed after deletion.
254
+ * Unlike {@link CopilotSession.disconnect}, which only releases in-memory
255
+ * resources and preserves session data for later resumption, this method
256
+ * is irreversible. The session cannot be resumed after deletion.
249
257
  *
250
258
  * @param sessionId - The ID of the session to delete
251
259
  * @returns A promise that resolves when the session is deleted
@@ -377,6 +385,18 @@ export declare class CopilotClient {
377
385
  private handleSessionLifecycleNotification;
378
386
  private handleUserInputRequest;
379
387
  private handleHooksInvoke;
388
+ /**
389
+ * Handles a v2-style tool.call RPC request from the server.
390
+ * Looks up the session and tool handler, executes it, and returns the result
391
+ * in the v2 response format.
392
+ */
393
+ private handleToolCallRequestV2;
394
+ /**
395
+ * Handles a v2-style permission.request RPC request from the server.
396
+ */
397
+ private handlePermissionRequestV2;
398
+ private normalizeToolResultV2;
399
+ private isToolResultObject;
380
400
  /**
381
401
  * Attempt to reconnect to the server
382
402
  */
package/dist/client.js CHANGED
@@ -11,6 +11,7 @@ import {
11
11
  import { createServerRpc } from "./generated/rpc.js";
12
12
  import { getSdkProtocolVersion } from "./sdkProtocolVersion.js";
13
13
  import { CopilotSession } from "./session.js";
14
+ const MIN_PROTOCOL_VERSION = 2;
14
15
  function isZodSchema(value) {
15
16
  return value != null && typeof value === "object" && "toJSONSchema" in value && typeof value.toJSONSchema === "function";
16
17
  }
@@ -52,6 +53,7 @@ class CopilotClient {
52
53
  _rpc = null;
53
54
  processExitPromise = null;
54
55
  // Rejects when CLI process exits
56
+ negotiatedProtocolVersion = null;
55
57
  /**
56
58
  * Typed server-scoped RPC methods.
57
59
  * @throws Error if the client is not connected
@@ -188,10 +190,14 @@ class CopilotClient {
188
190
  * Stops the CLI server and closes all active sessions.
189
191
  *
190
192
  * This method performs graceful cleanup:
191
- * 1. Destroys all active sessions with retry logic
193
+ * 1. Closes all active sessions (releases in-memory resources)
192
194
  * 2. Closes the JSON-RPC connection
193
195
  * 3. Terminates the CLI server process (if spawned by this client)
194
196
  *
197
+ * Note: session data on disk is preserved, so sessions can be resumed later.
198
+ * To permanently remove session data before stopping, call
199
+ * {@link deleteSession} for each session first.
200
+ *
195
201
  * @returns A promise that resolves with an array of errors encountered during cleanup.
196
202
  * An empty array indicates all cleanup succeeded.
197
203
  *
@@ -210,7 +216,7 @@ class CopilotClient {
210
216
  let lastError = null;
211
217
  for (let attempt = 1; attempt <= 3; attempt++) {
212
218
  try {
213
- await session.destroy();
219
+ await session.disconnect();
214
220
  lastError = null;
215
221
  break;
216
222
  } catch (error) {
@@ -224,7 +230,7 @@ class CopilotClient {
224
230
  if (lastError) {
225
231
  errors.push(
226
232
  new Error(
227
- `Failed to destroy session ${sessionId} after 3 attempts: ${lastError.message}`
233
+ `Failed to disconnect session ${sessionId} after 3 attempts: ${lastError.message}`
228
234
  )
229
235
  );
230
236
  }
@@ -578,10 +584,11 @@ class CopilotClient {
578
584
  }
579
585
  }
580
586
  /**
581
- * Verify that the server's protocol version matches the SDK's expected version
587
+ * Verify that the server's protocol version is within the supported range
588
+ * and store the negotiated version.
582
589
  */
583
590
  async verifyProtocolVersion() {
584
- const expectedVersion = getSdkProtocolVersion();
591
+ const maxVersion = getSdkProtocolVersion();
585
592
  let pingResult;
586
593
  if (this.processExitPromise) {
587
594
  pingResult = await Promise.race([this.ping(), this.processExitPromise]);
@@ -591,14 +598,15 @@ class CopilotClient {
591
598
  const serverVersion = pingResult.protocolVersion;
592
599
  if (serverVersion === void 0) {
593
600
  throw new Error(
594
- `SDK protocol version mismatch: SDK expects version ${expectedVersion}, but server does not report a protocol version. Please update your server to ensure compatibility.`
601
+ `SDK protocol version mismatch: SDK supports versions ${MIN_PROTOCOL_VERSION}-${maxVersion}, but server does not report a protocol version. Please update your server to ensure compatibility.`
595
602
  );
596
603
  }
597
- if (serverVersion !== expectedVersion) {
604
+ if (serverVersion < MIN_PROTOCOL_VERSION || serverVersion > maxVersion) {
598
605
  throw new Error(
599
- `SDK protocol version mismatch: SDK expects version ${expectedVersion}, but server reports version ${serverVersion}. Please update your SDK or server to ensure compatibility.`
606
+ `SDK protocol version mismatch: SDK supports versions ${MIN_PROTOCOL_VERSION}-${maxVersion}, but server reports version ${serverVersion}. Please update your SDK or server to ensure compatibility.`
600
607
  );
601
608
  }
609
+ this.negotiatedProtocolVersion = serverVersion;
602
610
  }
603
611
  /**
604
612
  * Gets the ID of the most recently updated session.
@@ -625,10 +633,12 @@ class CopilotClient {
625
633
  return response.sessionId;
626
634
  }
627
635
  /**
628
- * Deletes a session and its data from disk.
636
+ * Permanently deletes a session and all its data from disk, including
637
+ * conversation history, planning state, and artifacts.
629
638
  *
630
- * This permanently removes the session and all its conversation history.
631
- * The session cannot be resumed after deletion.
639
+ * Unlike {@link CopilotSession.disconnect}, which only releases in-memory
640
+ * resources and preserves session data for later resumption, this method
641
+ * is irreversible. The session cannot be resumed after deletion.
632
642
  *
633
643
  * @param sessionId - The ID of the session to delete
634
644
  * @returns A promise that resolves when the session is deleted
@@ -969,6 +979,14 @@ stderr: ${stderrOutput}`
969
979
  this.connection.onNotification("session.lifecycle", (notification) => {
970
980
  this.handleSessionLifecycleNotification(notification);
971
981
  });
982
+ this.connection.onRequest(
983
+ "tool.call",
984
+ async (params) => await this.handleToolCallRequestV2(params)
985
+ );
986
+ this.connection.onRequest(
987
+ "permission.request",
988
+ async (params) => await this.handlePermissionRequestV2(params)
989
+ );
972
990
  this.connection.onRequest(
973
991
  "userInput.request",
974
992
  async (params) => await this.handleUserInputRequest(params)
@@ -1041,6 +1059,98 @@ stderr: ${stderrOutput}`
1041
1059
  const output = await session._handleHooksInvoke(params.hookType, params.input);
1042
1060
  return { output };
1043
1061
  }
1062
+ // ========================================================================
1063
+ // Protocol v2 backward-compatibility adapters
1064
+ // ========================================================================
1065
+ /**
1066
+ * Handles a v2-style tool.call RPC request from the server.
1067
+ * Looks up the session and tool handler, executes it, and returns the result
1068
+ * in the v2 response format.
1069
+ */
1070
+ async handleToolCallRequestV2(params) {
1071
+ if (!params || typeof params.sessionId !== "string" || typeof params.toolCallId !== "string" || typeof params.toolName !== "string") {
1072
+ throw new Error("Invalid tool call payload");
1073
+ }
1074
+ const session = this.sessions.get(params.sessionId);
1075
+ if (!session) {
1076
+ throw new Error(`Unknown session ${params.sessionId}`);
1077
+ }
1078
+ const handler = session.getToolHandler(params.toolName);
1079
+ if (!handler) {
1080
+ return {
1081
+ result: {
1082
+ textResultForLlm: `Tool '${params.toolName}' is not supported by this client instance.`,
1083
+ resultType: "failure",
1084
+ error: `tool '${params.toolName}' not supported`,
1085
+ toolTelemetry: {}
1086
+ }
1087
+ };
1088
+ }
1089
+ try {
1090
+ const invocation = {
1091
+ sessionId: params.sessionId,
1092
+ toolCallId: params.toolCallId,
1093
+ toolName: params.toolName,
1094
+ arguments: params.arguments
1095
+ };
1096
+ const result = await handler(params.arguments, invocation);
1097
+ return { result: this.normalizeToolResultV2(result) };
1098
+ } catch (error) {
1099
+ const message = error instanceof Error ? error.message : String(error);
1100
+ return {
1101
+ result: {
1102
+ textResultForLlm: "Invoking this tool produced an error. Detailed information is not available.",
1103
+ resultType: "failure",
1104
+ error: message,
1105
+ toolTelemetry: {}
1106
+ }
1107
+ };
1108
+ }
1109
+ }
1110
+ /**
1111
+ * Handles a v2-style permission.request RPC request from the server.
1112
+ */
1113
+ async handlePermissionRequestV2(params) {
1114
+ if (!params || typeof params.sessionId !== "string" || !params.permissionRequest) {
1115
+ throw new Error("Invalid permission request payload");
1116
+ }
1117
+ const session = this.sessions.get(params.sessionId);
1118
+ if (!session) {
1119
+ throw new Error(`Session not found: ${params.sessionId}`);
1120
+ }
1121
+ try {
1122
+ const result = await session._handlePermissionRequestV2(params.permissionRequest);
1123
+ return { result };
1124
+ } catch (_error) {
1125
+ return {
1126
+ result: {
1127
+ kind: "denied-no-approval-rule-and-could-not-request-from-user"
1128
+ }
1129
+ };
1130
+ }
1131
+ }
1132
+ normalizeToolResultV2(result) {
1133
+ if (result === void 0 || result === null) {
1134
+ return {
1135
+ textResultForLlm: "Tool returned no result",
1136
+ resultType: "failure",
1137
+ error: "tool returned no result",
1138
+ toolTelemetry: {}
1139
+ };
1140
+ }
1141
+ if (this.isToolResultObject(result)) {
1142
+ return result;
1143
+ }
1144
+ const textResult = typeof result === "string" ? result : JSON.stringify(result);
1145
+ return {
1146
+ textResultForLlm: textResult,
1147
+ resultType: "success",
1148
+ toolTelemetry: {}
1149
+ };
1150
+ }
1151
+ isToolResultObject(value) {
1152
+ return typeof value === "object" && value !== null && "textResultForLlm" in value && typeof value.textResultForLlm === "string" && "resultType" in value;
1153
+ }
1044
1154
  /**
1045
1155
  * Attempt to reconnect to the server
1046
1156
  */
@@ -407,7 +407,14 @@ export interface SessionToolsHandlePendingToolCallParams {
407
407
  */
408
408
  sessionId: string;
409
409
  requestId: string;
410
- result?: string;
410
+ result?: string | {
411
+ textResultForLlm: string;
412
+ resultType?: string;
413
+ error?: string;
414
+ toolTelemetry?: {
415
+ [k: string]: unknown;
416
+ };
417
+ };
411
418
  error?: string;
412
419
  }
413
420
  export interface SessionPermissionsHandlePendingPermissionRequestResult {
@@ -420,8 +427,19 @@ export interface SessionPermissionsHandlePendingPermissionRequestParams {
420
427
  sessionId: string;
421
428
  requestId: string;
422
429
  result: {
423
- kind: "approved" | "denied-by-rules" | "denied-no-approval-rule-and-could-not-request-from-user" | "denied-interactively-by-user";
424
- rules?: unknown[];
430
+ kind: "approved";
431
+ } | {
432
+ kind: "denied-by-rules";
433
+ rules: unknown[];
434
+ } | {
435
+ kind: "denied-no-approval-rule-and-could-not-request-from-user";
436
+ } | {
437
+ kind: "denied-interactively-by-user";
438
+ feedback?: string;
439
+ } | {
440
+ kind: "denied-by-content-exclusion-policy";
441
+ path: string;
442
+ message: string;
425
443
  };
426
444
  }
427
445
  /** Create typed server-scoped RPC methods (no session required). */
package/dist/session.d.ts CHANGED
@@ -4,7 +4,7 @@
4
4
  */
5
5
  import type { MessageConnection } from "vscode-jsonrpc/node";
6
6
  import { createSessionRpc } from "./generated/rpc.js";
7
- import type { MessageOptions, PermissionHandler, SessionEvent, SessionEventHandler, SessionEventType, SessionHooks, Tool, ToolHandler, TypedSessionEventHandler, UserInputHandler, UserInputResponse } from "./types.js";
7
+ import type { MessageOptions, PermissionHandler, PermissionRequestResult, SessionEvent, SessionEventHandler, SessionEventType, SessionHooks, Tool, ToolHandler, TypedSessionEventHandler, UserInputHandler, UserInputResponse } from "./types.js";
8
8
  /** Assistant message event - the final response from the assistant. */
9
9
  export type AssistantMessageEvent = Extract<SessionEvent, {
10
10
  type: "assistant.message";
@@ -31,7 +31,7 @@ export type AssistantMessageEvent = Extract<SessionEvent, {
31
31
  * await session.sendAndWait({ prompt: "Hello, world!" });
32
32
  *
33
33
  * // Clean up
34
- * await session.destroy();
34
+ * await session.disconnect();
35
35
  * ```
36
36
  */
37
37
  export declare class CopilotSession {
@@ -72,7 +72,7 @@ export declare class CopilotSession {
72
72
  *
73
73
  * @param options - The message options including the prompt and optional attachments
74
74
  * @returns A promise that resolves with the message ID of the response
75
- * @throws Error if the session has been destroyed or the connection fails
75
+ * @throws Error if the session has been disconnected or the connection fails
76
76
  *
77
77
  * @example
78
78
  * ```typescript
@@ -97,7 +97,7 @@ export declare class CopilotSession {
97
97
  * @returns A promise that resolves with the final assistant message when the session becomes idle,
98
98
  * or undefined if no assistant message was received
99
99
  * @throws Error if the timeout is reached before the session becomes idle
100
- * @throws Error if the session has been destroyed or the connection fails
100
+ * @throws Error if the session has been disconnected or the connection fails
101
101
  *
102
102
  * @example
103
103
  * ```typescript
@@ -226,6 +226,15 @@ export declare class CopilotSession {
226
226
  * @internal This method is typically called internally when creating a session.
227
227
  */
228
228
  registerHooks(hooks?: SessionHooks): void;
229
+ /**
230
+ * Handles a permission request in the v2 protocol format (synchronous RPC).
231
+ * Used as a back-compat adapter when connected to a v2 server.
232
+ *
233
+ * @param request - The permission request data from the CLI
234
+ * @returns A promise that resolves with the permission decision
235
+ * @internal This method is for internal use by the SDK.
236
+ */
237
+ _handlePermissionRequestV2(request: unknown): Promise<PermissionRequestResult>;
229
238
  /**
230
239
  * Handles a user input request from the Copilot CLI.
231
240
  *
@@ -250,7 +259,7 @@ export declare class CopilotSession {
250
259
  * assistant responses, tool executions, and other session events.
251
260
  *
252
261
  * @returns A promise that resolves with an array of all session events
253
- * @throws Error if the session has been destroyed or the connection fails
262
+ * @throws Error if the session has been disconnected or the connection fails
254
263
  *
255
264
  * @example
256
265
  * ```typescript
@@ -264,22 +273,39 @@ export declare class CopilotSession {
264
273
  */
265
274
  getMessages(): Promise<SessionEvent[]>;
266
275
  /**
267
- * Destroys this session and releases all associated resources.
276
+ * Disconnects this session and releases all in-memory resources (event handlers,
277
+ * tool handlers, permission handlers).
278
+ *
279
+ * Session state on disk (conversation history, planning state, artifacts) is
280
+ * preserved, so the conversation can be resumed later by calling
281
+ * {@link CopilotClient.resumeSession} with the session ID. To permanently
282
+ * remove all session data including files on disk, use
283
+ * {@link CopilotClient.deleteSession} instead.
268
284
  *
269
- * After calling this method, the session can no longer be used. All event
270
- * handlers and tool handlers are cleared. To continue the conversation,
271
- * use {@link CopilotClient.resumeSession} with the session ID.
285
+ * After calling this method, the session object can no longer be used.
272
286
  *
273
- * @returns A promise that resolves when the session is destroyed
287
+ * @returns A promise that resolves when the session is disconnected
274
288
  * @throws Error if the connection fails
275
289
  *
276
290
  * @example
277
291
  * ```typescript
278
- * // Clean up when done
279
- * await session.destroy();
292
+ * // Clean up when done — session can still be resumed later
293
+ * await session.disconnect();
280
294
  * ```
281
295
  */
296
+ disconnect(): Promise<void>;
297
+ /**
298
+ * @deprecated Use {@link disconnect} instead. This method will be removed in a future release.
299
+ *
300
+ * Disconnects this session and releases all in-memory resources.
301
+ * Session data on disk is preserved for later resumption.
302
+ *
303
+ * @returns A promise that resolves when the session is disconnected
304
+ * @throws Error if the connection fails
305
+ */
282
306
  destroy(): Promise<void>;
307
+ /** Enables `await using session = ...` syntax for automatic cleanup. */
308
+ [Symbol.asyncDispose](): Promise<void>;
283
309
  /**
284
310
  * Aborts the currently processing message in this session.
285
311
  *
@@ -287,7 +313,7 @@ export declare class CopilotSession {
287
313
  * and can continue to be used for new messages.
288
314
  *
289
315
  * @returns A promise that resolves when the abort request is acknowledged
290
- * @throws Error if the session has been destroyed or the connection fails
316
+ * @throws Error if the session has been disconnected or the connection fails
291
317
  *
292
318
  * @example
293
319
  * ```typescript
package/dist/session.js CHANGED
@@ -1,3 +1,4 @@
1
+ import { ConnectionError, ResponseError } from "vscode-jsonrpc/node";
1
2
  import { createSessionRpc } from "./generated/rpc.js";
2
3
  class CopilotSession {
3
4
  /**
@@ -45,7 +46,7 @@ class CopilotSession {
45
46
  *
46
47
  * @param options - The message options including the prompt and optional attachments
47
48
  * @returns A promise that resolves with the message ID of the response
48
- * @throws Error if the session has been destroyed or the connection fails
49
+ * @throws Error if the session has been disconnected or the connection fails
49
50
  *
50
51
  * @example
51
52
  * ```typescript
@@ -78,7 +79,7 @@ class CopilotSession {
78
79
  * @returns A promise that resolves with the final assistant message when the session becomes idle,
79
80
  * or undefined if no assistant message was received
80
81
  * @throws Error if the timeout is reached before the session becomes idle
81
- * @throws Error if the session has been destroyed or the connection fails
82
+ * @throws Error if the session has been disconnected or the connection fails
82
83
  *
83
84
  * @example
84
85
  * ```typescript
@@ -220,7 +221,13 @@ class CopilotSession {
220
221
  await this.rpc.tools.handlePendingToolCall({ requestId, result });
221
222
  } catch (error) {
222
223
  const message = error instanceof Error ? error.message : String(error);
223
- await this.rpc.tools.handlePendingToolCall({ requestId, error: message });
224
+ try {
225
+ await this.rpc.tools.handlePendingToolCall({ requestId, error: message });
226
+ } catch (rpcError) {
227
+ if (!(rpcError instanceof ConnectionError || rpcError instanceof ResponseError)) {
228
+ throw rpcError;
229
+ }
230
+ }
224
231
  }
225
232
  }
226
233
  /**
@@ -234,12 +241,18 @@ class CopilotSession {
234
241
  });
235
242
  await this.rpc.permissions.handlePendingPermissionRequest({ requestId, result });
236
243
  } catch (_error) {
237
- await this.rpc.permissions.handlePendingPermissionRequest({
238
- requestId,
239
- result: {
240
- kind: "denied-no-approval-rule-and-could-not-request-from-user"
244
+ try {
245
+ await this.rpc.permissions.handlePendingPermissionRequest({
246
+ requestId,
247
+ result: {
248
+ kind: "denied-no-approval-rule-and-could-not-request-from-user"
249
+ }
250
+ });
251
+ } catch (rpcError) {
252
+ if (!(rpcError instanceof ConnectionError || rpcError instanceof ResponseError)) {
253
+ throw rpcError;
241
254
  }
242
- });
255
+ }
243
256
  }
244
257
  }
245
258
  /**
@@ -306,6 +319,27 @@ class CopilotSession {
306
319
  registerHooks(hooks) {
307
320
  this.hooks = hooks;
308
321
  }
322
+ /**
323
+ * Handles a permission request in the v2 protocol format (synchronous RPC).
324
+ * Used as a back-compat adapter when connected to a v2 server.
325
+ *
326
+ * @param request - The permission request data from the CLI
327
+ * @returns A promise that resolves with the permission decision
328
+ * @internal This method is for internal use by the SDK.
329
+ */
330
+ async _handlePermissionRequestV2(request) {
331
+ if (!this.permissionHandler) {
332
+ return { kind: "denied-no-approval-rule-and-could-not-request-from-user" };
333
+ }
334
+ try {
335
+ const result = await this.permissionHandler(request, {
336
+ sessionId: this.sessionId
337
+ });
338
+ return result;
339
+ } catch (_error) {
340
+ return { kind: "denied-no-approval-rule-and-could-not-request-from-user" };
341
+ }
342
+ }
309
343
  /**
310
344
  * Handles a user input request from the Copilot CLI.
311
345
  *
@@ -364,7 +398,7 @@ class CopilotSession {
364
398
  * assistant responses, tool executions, and other session events.
365
399
  *
366
400
  * @returns A promise that resolves with an array of all session events
367
- * @throws Error if the session has been destroyed or the connection fails
401
+ * @throws Error if the session has been disconnected or the connection fails
368
402
  *
369
403
  * @example
370
404
  * ```typescript
@@ -383,22 +417,27 @@ class CopilotSession {
383
417
  return response.events;
384
418
  }
385
419
  /**
386
- * Destroys this session and releases all associated resources.
420
+ * Disconnects this session and releases all in-memory resources (event handlers,
421
+ * tool handlers, permission handlers).
387
422
  *
388
- * After calling this method, the session can no longer be used. All event
389
- * handlers and tool handlers are cleared. To continue the conversation,
390
- * use {@link CopilotClient.resumeSession} with the session ID.
423
+ * Session state on disk (conversation history, planning state, artifacts) is
424
+ * preserved, so the conversation can be resumed later by calling
425
+ * {@link CopilotClient.resumeSession} with the session ID. To permanently
426
+ * remove all session data including files on disk, use
427
+ * {@link CopilotClient.deleteSession} instead.
391
428
  *
392
- * @returns A promise that resolves when the session is destroyed
429
+ * After calling this method, the session object can no longer be used.
430
+ *
431
+ * @returns A promise that resolves when the session is disconnected
393
432
  * @throws Error if the connection fails
394
433
  *
395
434
  * @example
396
435
  * ```typescript
397
- * // Clean up when done
398
- * await session.destroy();
436
+ * // Clean up when done — session can still be resumed later
437
+ * await session.disconnect();
399
438
  * ```
400
439
  */
401
- async destroy() {
440
+ async disconnect() {
402
441
  await this.connection.sendRequest("session.destroy", {
403
442
  sessionId: this.sessionId
404
443
  });
@@ -407,6 +446,22 @@ class CopilotSession {
407
446
  this.toolHandlers.clear();
408
447
  this.permissionHandler = void 0;
409
448
  }
449
+ /**
450
+ * @deprecated Use {@link disconnect} instead. This method will be removed in a future release.
451
+ *
452
+ * Disconnects this session and releases all in-memory resources.
453
+ * Session data on disk is preserved for later resumption.
454
+ *
455
+ * @returns A promise that resolves when the session is disconnected
456
+ * @throws Error if the connection fails
457
+ */
458
+ async destroy() {
459
+ return this.disconnect();
460
+ }
461
+ /** Enables `await using session = ...` syntax for automatic cleanup. */
462
+ async [Symbol.asyncDispose]() {
463
+ return this.disconnect();
464
+ }
410
465
  /**
411
466
  * Aborts the currently processing message in this session.
412
467
  *
@@ -414,7 +469,7 @@ class CopilotSession {
414
469
  * and can continue to be used for new messages.
415
470
  *
416
471
  * @returns A promise that resolves when the abort request is acknowledged
417
- * @throws Error if the session has been destroyed or the connection fails
472
+ * @throws Error if the session has been disconnected or the connection fails
418
473
  *
419
474
  * @example
420
475
  * ```typescript
package/dist/types.d.ts CHANGED
@@ -185,10 +185,8 @@ export interface PermissionRequest {
185
185
  toolCallId?: string;
186
186
  [key: string]: unknown;
187
187
  }
188
- export interface PermissionRequestResult {
189
- kind: "approved" | "denied-by-rules" | "denied-no-approval-rule-and-could-not-request-from-user" | "denied-interactively-by-user";
190
- rules?: unknown[];
191
- }
188
+ import type { SessionPermissionsHandlePendingPermissionRequestParams } from "./generated/rpc.js";
189
+ export type PermissionRequestResult = SessionPermissionsHandlePendingPermissionRequestParams["result"];
192
190
  export type PermissionHandler = (request: PermissionRequest, invocation: {
193
191
  sessionId: string;
194
192
  }) => Promise<PermissionRequestResult> | PermissionRequestResult;
package/package.json CHANGED
@@ -4,7 +4,7 @@
4
4
  "type": "git",
5
5
  "url": "https://github.com/github/copilot-sdk.git"
6
6
  },
7
- "version": "0.1.31-unstable.0",
7
+ "version": "0.1.32",
8
8
  "description": "TypeScript SDK for programmatic control of GitHub Copilot CLI via JSON-RPC",
9
9
  "main": "./dist/index.js",
10
10
  "types": "./dist/index.d.ts",
@@ -44,7 +44,7 @@
44
44
  "author": "GitHub",
45
45
  "license": "MIT",
46
46
  "dependencies": {
47
- "@github/copilot": "^0.0.421",
47
+ "@github/copilot": "^1.0.2",
48
48
  "vscode-jsonrpc": "^8.2.1",
49
49
  "zod": "^4.3.6"
50
50
  },