@github/copilot-sdk 1.0.16 → 1.0.17-preview.1

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.
@@ -254,6 +254,7 @@ class CopilotSession {
254
254
  sessionId;
255
255
  connection;
256
256
  _workspacePath;
257
+ _transcriptRecovery;
257
258
  eventHandlers = /* @__PURE__ */ new Set();
258
259
  typedEventHandlers = /* @__PURE__ */ new Map();
259
260
  toolHandlers = /* @__PURE__ */ new Map();
@@ -443,6 +444,14 @@ class CopilotSession {
443
444
  get workspacePath() {
444
445
  return this._workspacePath;
445
446
  }
447
+ /** Recovery observed while loading this session; undefined on a clean resume. */
448
+ get transcriptRecovery() {
449
+ return this._transcriptRecovery;
450
+ }
451
+ /** @internal */
452
+ setTranscriptRecovery(recovery) {
453
+ this._transcriptRecovery = recovery;
454
+ }
446
455
  /**
447
456
  * Host capabilities reported when the session was created or resumed.
448
457
  * Use this to check feature support before calling capability-gated APIs.
@@ -1,2 +1,2 @@
1
- export declare const COPILOT_CLI_VERSION = "1.0.90";
1
+ export declare const COPILOT_CLI_VERSION = "1.0.92-1";
2
2
  export declare const COPILOT_CLI_USE_NPM_PACKAGE = false;
@@ -1,4 +1,4 @@
1
- const COPILOT_CLI_VERSION = "1.0.90";
1
+ const COPILOT_CLI_VERSION = "1.0.92-1";
2
2
  const COPILOT_CLI_USE_NPM_PACKAGE = false;
3
3
  export {
4
4
  COPILOT_CLI_USE_NPM_PACKAGE,
package/dist/client.d.ts CHANGED
@@ -10,6 +10,7 @@ export declare class CopilotClient {
10
10
  private requestAdapter;
11
11
  private messageWriter;
12
12
  private connectionClosed;
13
+ private connectionEpoch;
13
14
  private socket;
14
15
  private runtimePort;
15
16
  private actualHost;
package/dist/client.js CHANGED
@@ -262,6 +262,7 @@ class CopilotClient {
262
262
  requestAdapter = null;
263
263
  messageWriter = null;
264
264
  connectionClosed = false;
265
+ connectionEpoch = 0;
265
266
  socket = null;
266
267
  runtimePort = null;
267
268
  actualHost = "localhost";
@@ -671,6 +672,7 @@ class CopilotClient {
671
672
  }
672
673
  async doStart() {
673
674
  this.forceStopping = false;
675
+ this.connectionEpoch++;
674
676
  this.connectionClosed = false;
675
677
  this.processTransportError = null;
676
678
  this.state = "connecting";
@@ -706,6 +708,9 @@ class CopilotClient {
706
708
  if (this.requestHandler) {
707
709
  await this.connection.sendRequest("llmInference.setProvider", {});
708
710
  }
711
+ if (this.connectionClosed) {
712
+ throw new Error("CLI server connection closed during startup");
713
+ }
709
714
  this.state = "connected";
710
715
  } catch (error) {
711
716
  const startupError = this.processTransportError ?? error;
@@ -825,10 +830,23 @@ class CopilotClient {
825
830
  this.socket = null;
826
831
  try {
827
832
  if (!socket.destroyed) {
828
- await new Promise((resolve2) => {
829
- socket.once("close", () => resolve2());
830
- socket.end();
831
- });
833
+ let timeout;
834
+ try {
835
+ await new Promise((resolve2) => {
836
+ socket.once("close", () => resolve2());
837
+ if (this.connectionClosed) {
838
+ socket.destroy();
839
+ } else {
840
+ timeout = setTimeout(
841
+ () => socket.destroy(),
842
+ RUNTIME_SHUTDOWN_TIMEOUT_MS
843
+ );
844
+ socket.end();
845
+ }
846
+ });
847
+ } finally {
848
+ if (timeout !== void 0) clearTimeout(timeout);
849
+ }
832
850
  }
833
851
  } catch (error) {
834
852
  errors.push(
@@ -1491,6 +1509,7 @@ class CopilotClient {
1491
1509
  allowedModels: config.allowedModels,
1492
1510
  ...await getTraceContext(this.onGetTraceContext),
1493
1511
  sessionId,
1512
+ allowTranscriptRecovery: config.allowTranscriptRecovery,
1494
1513
  clientName: config.clientName,
1495
1514
  model: config.model,
1496
1515
  reasoningEffort: config.reasoningEffort,
@@ -1597,10 +1616,11 @@ class CopilotClient {
1597
1616
  }
1598
1617
  }
1599
1618
  }
1600
- const { workspacePath, capabilities, openCanvases } = response;
1619
+ const { workspacePath, capabilities, openCanvases, transcriptRecovery } = response;
1601
1620
  session["_workspacePath"] = workspacePath;
1602
1621
  session.setCapabilities(capabilities);
1603
1622
  session.setOpenCanvases(openCanvases ?? []);
1623
+ session.setTranscriptRecovery(transcriptRecovery);
1604
1624
  if (config.onMcpAuthRequest) {
1605
1625
  await this.connection.sendRequest("session.eventLog.registerInterest", {
1606
1626
  sessionId,
@@ -2589,8 +2609,13 @@ stderr: ${stderrOutput}` : ""}`
2589
2609
  );
2590
2610
  const connection = this.connection;
2591
2611
  const messageWriter = this.messageWriter;
2612
+ const cliProcess = this.isExternalServer ? null : this.cliProcess;
2613
+ const connectionEpoch = this.connectionEpoch;
2614
+ const isCurrentConnection = () => connectionEpoch === this.connectionEpoch && this.connection === connection && (cliProcess === null || this.cliProcess === cliProcess);
2615
+ let disconnecting = false;
2616
+ let exitFallback;
2592
2617
  const markDisconnected = () => {
2593
- if (this.connection !== connection) {
2618
+ if (!isCurrentConnection()) {
2594
2619
  connection.dispose();
2595
2620
  return;
2596
2621
  }
@@ -2604,13 +2629,48 @@ stderr: ${stderrOutput}` : ""}`
2604
2629
  this.githubTokenProviders.clear();
2605
2630
  this.requestAdapter?.cancelPending();
2606
2631
  connection.dispose();
2632
+ this.socket?.destroy();
2633
+ this.connection = null;
2634
+ this.messageWriter = null;
2635
+ this._rpc = null;
2636
+ this._internalRpc = null;
2637
+ this.modelsCache = null;
2607
2638
  };
2608
- this.connection.onClose(() => {
2639
+ const disconnectAfterDrain = () => {
2640
+ if (exitFallback !== void 0) {
2641
+ clearTimeout(exitFallback);
2642
+ exitFallback = void 0;
2643
+ }
2644
+ if (!isCurrentConnection()) {
2645
+ connection.dispose();
2646
+ return;
2647
+ }
2648
+ if (disconnecting) return;
2649
+ disconnecting = true;
2650
+ this.connectionClosed = true;
2609
2651
  if (messageWriter) messageWriter.suppressWriteErrors = true;
2610
2652
  void connection.drain().then(markDisconnected);
2611
- });
2653
+ };
2654
+ this.connection.onClose(disconnectAfterDrain);
2655
+ if (cliProcess) {
2656
+ cliProcess.once("exit", () => {
2657
+ if (!isCurrentConnection()) {
2658
+ connection.dispose();
2659
+ return;
2660
+ }
2661
+ if (disconnecting) return;
2662
+ if (this.socket) {
2663
+ disconnectAfterDrain();
2664
+ return;
2665
+ }
2666
+ this.connectionClosed = true;
2667
+ if (messageWriter) messageWriter.suppressWriteErrors = true;
2668
+ exitFallback = setTimeout(disconnectAfterDrain, RUNTIME_SHUTDOWN_TIMEOUT_MS);
2669
+ exitFallback.unref();
2670
+ });
2671
+ }
2612
2672
  this.connection.onError(() => {
2613
- if (this.connection === connection) {
2673
+ if (connectionEpoch === this.connectionEpoch && this.connection === connection) {
2614
2674
  this.state = "disconnected";
2615
2675
  }
2616
2676
  });
@@ -33,6 +33,7 @@ export declare class FfiRuntimeHost {
33
33
  * bytes are copied out before returning.
34
34
  */
35
35
  private feedInbound;
36
+ private shutdownHost;
36
37
  private unregisterCallback;
37
38
  private scheduleCleanupRetry;
38
39
  private tryFinalizeCleanup;
@@ -175,7 +175,7 @@ class FfiRuntimeHost {
175
175
  );
176
176
  if (!this.connectionId) {
177
177
  this.unregisterCallback();
178
- this.lib.hostShutdown(this.serverId);
178
+ await this.shutdownHost();
179
179
  this.serverId = 0;
180
180
  throw new Error("copilot_runtime_connection_open failed.");
181
181
  }
@@ -184,7 +184,7 @@ class FfiRuntimeHost {
184
184
  } finally {
185
185
  this.starting = false;
186
186
  if (this.disposed) {
187
- void this.tryFinalizeCleanup();
187
+ await this.tryFinalizeCleanup();
188
188
  }
189
189
  }
190
190
  }
@@ -223,6 +223,17 @@ class FfiRuntimeHost {
223
223
  );
224
224
  }
225
225
  }
226
+ shutdownHost() {
227
+ return new Promise((resolvePromise, rejectPromise) => {
228
+ this.lib.hostShutdown.async(this.serverId, (error, result) => {
229
+ if (error) {
230
+ rejectPromise(error);
231
+ } else {
232
+ resolvePromise(result);
233
+ }
234
+ });
235
+ });
236
+ }
226
237
  unregisterCallback() {
227
238
  if (this.outboundCallback === void 0) {
228
239
  return true;
@@ -295,7 +306,7 @@ class FfiRuntimeHost {
295
306
  }
296
307
  if (this.serverId) {
297
308
  try {
298
- if (!this.lib.hostShutdown(this.serverId)) {
309
+ if (!await this.shutdownHost()) {
299
310
  console.error(
300
311
  `In-process FFI host shutdown did not recognize server ${this.serverId}.`
301
312
  );