@github/copilot-sdk 1.0.28-preview.0 → 1.0.29-preview.0

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/dist/client.js CHANGED
@@ -9,7 +9,7 @@ import {
9
9
  ResponseError,
10
10
  StreamMessageReader,
11
11
  StreamMessageWriter
12
- } from "vscode-jsonrpc/node.js";
12
+ } from "vscode-jsonrpc/node";
13
13
  import {
14
14
  createServerRpc,
15
15
  createInternalServerRpc,
@@ -28,6 +28,7 @@ import { createCopilotRequestAdapter } from "./copilotRequestHandler.js";
28
28
  import {
29
29
  createInstallationConfirmationAdapter
30
30
  } from "./installationConfirmation.js";
31
+ import { registerEntraTokenProvider } from "./entra.js";
31
32
  import { getTraceContext } from "./telemetry.js";
32
33
  import { toJsonSchema } from "./schema.js";
33
34
  import { ToolSet } from "./toolSet.js";
@@ -130,6 +131,30 @@ async function waitForChildExit(child, timeoutMs) {
130
131
  }
131
132
  });
132
133
  }
134
+ async function acquireKerberosToken(connection, callback, request, token) {
135
+ const ended = () => token.isCancellationRequested ? new ResponseError(-32800, "Kerberos auth request cancelled") : new Error("Kerberos auth connection closed");
136
+ if (token.isCancellationRequested) {
137
+ throw ended();
138
+ }
139
+ const controller = new AbortController();
140
+ const abandoned = new Promise((_resolve, reject) => {
141
+ controller.signal.addEventListener("abort", () => reject(ended()), { once: true });
142
+ });
143
+ const abort = () => controller.abort();
144
+ const subscriptions = [
145
+ token.onCancellationRequested(abort),
146
+ connection.onClose(abort),
147
+ connection.onDispose(abort)
148
+ ];
149
+ try {
150
+ const lookup = Promise.resolve().then(() => callback(request, controller.signal));
151
+ return { token: await Promise.race([lookup, abandoned]) };
152
+ } finally {
153
+ for (const subscription of subscriptions) {
154
+ subscription.dispose();
155
+ }
156
+ }
157
+ }
133
158
  const DEFAULT_PROVIDER_NAME = "default";
134
159
  function extractBearerTokenProviders(provider, providers) {
135
160
  const callbacks = /* @__PURE__ */ new Map();
@@ -307,6 +332,7 @@ class CopilotClient {
307
332
  sessionFsConfig = null;
308
333
  requestHandler = null;
309
334
  extensionLaunchProvider;
335
+ kerberosAuth;
310
336
  installationConfirmationHandler;
311
337
  builtinPluginDirectories = [];
312
338
  onGitHubTelemetry;
@@ -466,6 +492,7 @@ class CopilotClient {
466
492
  this.sessionFsConfig = options.sessionFs ?? null;
467
493
  this.requestHandler = options.requestHandler ?? null;
468
494
  this.extensionLaunchProvider = options.extensionLaunchProvider;
495
+ this.kerberosAuth = options.kerberosAuth;
469
496
  this.installationConfirmationHandler = options.installationConfirmationHandler;
470
497
  this.onGitHubTelemetry = options.onGitHubTelemetry;
471
498
  this.setupClientGlobalHandlers();
@@ -481,7 +508,7 @@ class CopilotClient {
481
508
  const connArgs = conn.kind === "stdio" || conn.kind === "tcp" ? conn.args ?? [] : [];
482
509
  this.connectionExtraArgs = [...connArgs];
483
510
  this.options = {
484
- entra: options.entra ? { ...options.entra } : void 0,
511
+ entra: options.entra ? { ...options.entra, tokenProvider: options.entra.tokenProvider } : void 0,
485
512
  workingDirectory: options.workingDirectory ?? process.cwd(),
486
513
  logLevel: options.logLevel,
487
514
  gitHubToken: options.gitHubToken,
@@ -570,6 +597,11 @@ class CopilotClient {
570
597
  "SessionFsConfig declares capabilities.binary but the provider does not implement readFileBytes and writeFileBytes."
571
598
  );
572
599
  }
600
+ if (this.sessionFsConfig.capabilities?.readFileRange && !provider.readFileRange) {
601
+ throw new Error(
602
+ "SessionFsConfig declares capabilities.readFileRange but the provider does not implement readFileRange."
603
+ );
604
+ }
573
605
  session.clientSessionApis.sessionFs = createSessionFsAdapter(provider);
574
606
  }
575
607
  setupClientGlobalHandlers() {
@@ -704,6 +736,10 @@ class CopilotClient {
704
736
  }
705
737
  await this.connectToServer();
706
738
  await this.verifyProtocolVersion();
739
+ if (this.kerberosAuth) {
740
+ const { mode, scope } = this.kerberosAuth;
741
+ await this.rpc.kerberosAuth.setProvider(scope ? { mode, scope } : { mode });
742
+ }
707
743
  if (this.extensionLaunchProvider) {
708
744
  await this.rpc.registerExtensionLaunchProvider();
709
745
  }
@@ -1218,7 +1254,7 @@ class CopilotClient {
1218
1254
  if (config.cloud != null && config.skillProvider) {
1219
1255
  throw new Error("Skill providers are not supported for cloud sessions.");
1220
1256
  }
1221
- if (!this.connection) {
1257
+ if (!this.connection || this.startPromise) {
1222
1258
  await this.start();
1223
1259
  }
1224
1260
  const modeDefaults = this.configDefaultsForMode();
@@ -1372,6 +1408,7 @@ class CopilotClient {
1372
1408
  ...this.onGitHubTelemetry != null ? { enableGitHubTelemetryForwarding: true } : {},
1373
1409
  mcpServers: toWireMcpServers(config.mcpServers),
1374
1410
  ...config.diagnostics !== void 0 ? { diagnostics: config.diagnostics } : {},
1411
+ ...config.lifecycleDiagnostics !== void 0 ? { lifecycleDiagnostics: config.lifecycleDiagnostics } : {},
1375
1412
  mcpOAuthTokenStorage: config.mcpOAuthTokenStorage,
1376
1413
  authClientIdMetadataUrl: config.authClientIdMetadataUrl,
1377
1414
  envValueMode: "direct",
@@ -1509,7 +1546,7 @@ class CopilotClient {
1509
1546
  if (config.gitHubToken !== void 0 && config.gitHubTokenProvider !== void 0) {
1510
1547
  throw new Error("gitHubToken and gitHubTokenProvider are mutually exclusive");
1511
1548
  }
1512
- if (!this.connection) {
1549
+ if (!this.connection || this.startPromise) {
1513
1550
  await this.start();
1514
1551
  }
1515
1552
  const session = new CopilotSession(
@@ -1657,6 +1694,7 @@ class CopilotClient {
1657
1694
  ...this.onGitHubTelemetry != null ? { enableGitHubTelemetryForwarding: true } : {},
1658
1695
  mcpServers: toWireMcpServers(config.mcpServers),
1659
1696
  ...config.diagnostics !== void 0 ? { diagnostics: config.diagnostics } : {},
1697
+ ...config.lifecycleDiagnostics !== void 0 ? { lifecycleDiagnostics: config.lifecycleDiagnostics } : {},
1660
1698
  mcpOAuthTokenStorage: config.mcpOAuthTokenStorage,
1661
1699
  authClientIdMetadataUrl: config.authClientIdMetadataUrl,
1662
1700
  envValueMode: "direct",
@@ -2087,7 +2125,11 @@ class CopilotClient {
2087
2125
  let serverVersion;
2088
2126
  try {
2089
2127
  const connectParams = {
2090
- entra: this.options.entra,
2128
+ entra: this.options.entra && {
2129
+ clientId: this.options.entra.clientId,
2130
+ matsAppName: this.options.entra.matsAppName
2131
+ },
2132
+ entraTokenProvider: this.options.entra?.tokenProvider ? true : void 0,
2091
2133
  token: this.effectiveConnectionToken,
2092
2134
  supportedTaskKinds: ["agent", "client", "shell"]
2093
2135
  };
@@ -2099,6 +2141,9 @@ class CopilotClient {
2099
2141
  connectParams.clientInfo = clientInfo;
2100
2142
  }
2101
2143
  const result = await raceAgainstExit(this.internalRpc.connect(connectParams));
2144
+ if (this.options.entra?.tokenProvider && result.entraTokenProvider !== true) {
2145
+ throw new Error("This runtime does not support host-owned Entra token providers.");
2146
+ }
2102
2147
  serverVersion = result.protocolVersion;
2103
2148
  } catch (err) {
2104
2149
  if (err instanceof ResponseError && (err.code === ErrorCodes.MethodNotFound || err.message === "Unhandled method connect")) {
@@ -2355,8 +2400,10 @@ class CopilotClient {
2355
2400
  if (t.filePath !== void 0) env.COPILOT_OTEL_FILE_EXPORTER_PATH = t.filePath;
2356
2401
  if (t.exporterType !== void 0) env.COPILOT_OTEL_EXPORTER_TYPE = t.exporterType;
2357
2402
  if (t.sourceName !== void 0) env.COPILOT_OTEL_SOURCE_NAME = t.sourceName;
2358
- if (t.captureContent !== void 0)
2403
+ if (t.captureContent !== void 0) {
2404
+ env.OTEL_INSTRUMENTATION_GENAI_CAPTURE_CONTENT = t.captureContent ? "SPAN_ONLY" : "NO_CONTENT";
2359
2405
  env.OTEL_INSTRUMENTATION_GENAI_CAPTURE_MESSAGE_CONTENT = String(t.captureContent);
2406
+ }
2360
2407
  }
2361
2408
  return env;
2362
2409
  }
@@ -2737,6 +2784,9 @@ stderr: ${stderrOutput}` : ""}`
2737
2784
  return session.clientSessionApis;
2738
2785
  });
2739
2786
  registerClientGlobalApiHandlers(this.connection, this.clientGlobalHandlers);
2787
+ if (this.options.entra?.tokenProvider) {
2788
+ registerEntraTokenProvider(this.connection, this.options.entra.tokenProvider);
2789
+ }
2740
2790
  if (this.installationConfirmationHandler) {
2741
2791
  const confirmation = createInstallationConfirmationAdapter(
2742
2792
  this.connection,
@@ -2747,6 +2797,14 @@ stderr: ${stderrOutput}` : ""}`
2747
2797
  (params, token) => confirmation.confirm(params, token)
2748
2798
  );
2749
2799
  }
2800
+ if (this.kerberosAuth) {
2801
+ const { callback } = this.kerberosAuth;
2802
+ const connection2 = this.connection;
2803
+ this.connection.onRequest(
2804
+ "kerberosAuth.acquire",
2805
+ (params, token) => acquireKerberosToken(connection2, callback, params, token)
2806
+ );
2807
+ }
2750
2808
  this.connection.onRequest(
2751
2809
  "host.materializeSession",
2752
2810
  (params) => this.createHostSession(params)
@@ -0,0 +1,3 @@
1
+ import type { MessageConnection } from "./jsonrpcTypes.js";
2
+ import type { EntraTokenProvider } from "./types.js";
3
+ export declare function registerEntraTokenProvider(connection: MessageConnection, provider: EntraTokenProvider): void;
package/dist/entra.js ADDED
@@ -0,0 +1,59 @@
1
+ import { CancellationTokenSource, ResponseError } from "vscode-jsonrpc/node";
2
+ function registerEntraTokenProvider(connection, provider) {
3
+ const closed = new CancellationTokenSource();
4
+ const connectionClosed = closed.token;
5
+ const close = connection.onClose(() => closed.cancel());
6
+ const dispose = connection.onDispose(() => {
7
+ closed.cancel();
8
+ closed.dispose();
9
+ close.dispose();
10
+ dispose.dispose();
11
+ });
12
+ connection.onRequest(
13
+ "entraToken.getToken",
14
+ async ({ request }, token) => {
15
+ const combined = new CancellationTokenSource();
16
+ const subscriptions = [];
17
+ const checkCancellation = () => {
18
+ if (connectionClosed.isCancellationRequested || token.isCancellationRequested) {
19
+ combined.cancel();
20
+ throw new ResponseError(-32800, "Entra token acquisition cancelled");
21
+ }
22
+ };
23
+ try {
24
+ const cancelled = new Promise((_resolve, reject) => {
25
+ const cancel = () => {
26
+ combined.cancel();
27
+ reject(new ResponseError(-32800, "Entra token acquisition cancelled"));
28
+ };
29
+ subscriptions.push(
30
+ token.onCancellationRequested(cancel),
31
+ connectionClosed.onCancellationRequested(cancel)
32
+ );
33
+ });
34
+ checkCancellation();
35
+ const result = await Promise.race([
36
+ Promise.resolve().then(() => {
37
+ checkCancellation();
38
+ return provider(request, combined.token);
39
+ }),
40
+ cancelled
41
+ ]);
42
+ checkCancellation();
43
+ if (result === void 0 || result === null) {
44
+ throw new ResponseError(-32603, "Entra token provider failed");
45
+ }
46
+ return result;
47
+ } catch {
48
+ checkCancellation();
49
+ throw new ResponseError(-32603, "Entra token provider failed");
50
+ } finally {
51
+ for (const subscription of subscriptions) subscription.dispose();
52
+ combined.dispose();
53
+ }
54
+ }
55
+ );
56
+ }
57
+ export {
58
+ registerEntraTokenProvider
59
+ };
@@ -42,7 +42,7 @@ export type JoinSessionConfig = Omit<ResumeSessionConfig, "onPermissionRequest"
42
42
  workflows?: WorkflowHandle[];
43
43
  };
44
44
  export type { ExtensionInfo } from "./types.js";
45
- export { defineWorkflow, WorkflowResumeError, isWorkflowRunTerminal, type WorkflowRunOptions, type WorkflowResumeOptions, type WorkflowLimitOverrides, type WorkflowResumeErrorCode, type SessionWorkflowApi, type WorkflowAgentOptions, type WorkflowContext, type WorkflowDefinition, type WorkflowHandle, type JsonValue, type WorkflowJsonSchema, type WorkflowLimits, type WorkflowMeta, type WorkflowPipelineStage, type WorkflowStepOptions, type WorkflowRunResult, type WorkflowRunStatus, type WorkflowRunSummary, type WorkflowListRunsOptions, type WorkflowRunsPage, type WorkflowRunDetail, type WorkflowProgressPage, type WorkflowProgressLine, type WorkflowPhaseObservation, type WorkflowPhaseStatus, type WorkflowAgentSummary, } from "./workflow.js";
45
+ export { defineWorkflow, WorkflowResumeError, isWorkflowRunTerminal, type WorkflowRunOptions, type WorkflowResumeOptions, type WorkflowLimitOverrides, type WorkflowResumeErrorCode, type SessionWorkflowApi, type WorkflowAgentOptions, type WorkflowContext, type WorkflowDefinition, type WorkflowHandle, type JsonValue, type WorkflowJsonSchema, type WorkflowLimits, type WorkflowMeta, type WorkflowPipelineStage, type WorkflowStepOptions, type WorkflowRunResult, type WorkflowRunStatus, type WorkflowRunSummary, type WorkflowListRunsOptions, type WorkflowRunsPage, type WorkflowRunDetail, type WorkflowProgressPage, type WorkflowProgressLine, type WorkflowPhaseObservation, type WorkflowPhaseStatus, type WorkflowAgentContextObservation, type WorkflowAgentModelObservation, type WorkflowAgentReasoningEffortObservation, type WorkflowAgentSummary, } from "./workflow.js";
46
46
  /**
47
47
  * Joins the current foreground session.
48
48
  *
@@ -0,0 +1,220 @@
1
+ /**
2
+ * AUTO-GENERATED FILE - DO NOT EDIT
3
+ * Generated from: lifecycle-diagnostics.schema.json
4
+ */
5
+ /**
6
+ * Union of experimental lifecycle diagnostic event variants emitted by the Copilot CLI runtime.
7
+ */
8
+ export type LifecycleDiagnosticEvent = RuntimeLifecycleSystemStateDiagnosticEvent | RuntimeLifecycleProgressStateDiagnosticEvent;
9
+ /**
10
+ * How a settled lifecycle operation or progress record ended.
11
+ */
12
+ export type RuntimeLifecycleDisposition = "succeeded" | "failed" | "cancelled" | "timed_out" | "superseded" | "abandoned";
13
+ /**
14
+ * Lifecycle diagnostic event "runtime.lifecycle.system_state". Experimental, ephemeral, observational-only state of one runtime system after an operation transition. Observation and delivery never control runtime work. Process death, diagnostic projection loss, transport loss, or serialization failure can prevent external delivery.
15
+ */
16
+ export interface RuntimeLifecycleSystemStateDiagnosticEvent {
17
+ data: RuntimeLifecycleSystemStateData;
18
+ /**
19
+ * ISO 8601 timestamp when the lifecycle diagnostic event was projected.
20
+ */
21
+ timestamp: string;
22
+ /**
23
+ * Type discriminator. Always "runtime.lifecycle.system_state".
24
+ */
25
+ type: "runtime.lifecycle.system_state";
26
+ }
27
+ /**
28
+ * Experimental, observational-only state of one runtime system after an operation transition. Observation and delivery never control runtime work. Process death, diagnostic projection loss, transport loss, or serialization failure can prevent external delivery.
29
+ */
30
+ export interface RuntimeLifecycleSystemStateData {
31
+ /**
32
+ * Complete active operation set after applying the change.
33
+ */
34
+ activeOperations: RuntimeLifecycleOperation[];
35
+ changedOperation: RuntimeLifecycleOperation;
36
+ /**
37
+ * Authoritative condition retained after this change. Initial shared values are `current`, `disabled`, `degraded`, and `quiescent`; integrations can add bounded values as the contract matures.
38
+ */
39
+ condition?: string;
40
+ /**
41
+ * Opaque identity for one session registry generation.
42
+ */
43
+ incarnationId: string;
44
+ /**
45
+ * Session whose lifecycle owns this system.
46
+ */
47
+ sessionId: string;
48
+ /**
49
+ * Stable subsystem identifier.
50
+ */
51
+ system: string;
52
+ /**
53
+ * Orders every observed change to this system in the incarnation.
54
+ */
55
+ systemRevision: number;
56
+ }
57
+ /**
58
+ * Observed state of one readiness or convergence operation.
59
+ */
60
+ export interface RuntimeLifecycleOperation {
61
+ disposition?: RuntimeLifecycleDisposition;
62
+ /**
63
+ * Opaque operation identifier, unique within the lifecycle incarnation and system.
64
+ */
65
+ operationId: string;
66
+ /**
67
+ * Orders transitions of this operation.
68
+ */
69
+ operationRevision: number;
70
+ /**
71
+ * System-owned lifecycle stage.
72
+ */
73
+ phase: string;
74
+ /**
75
+ * System-owned production boundary within the phase.
76
+ */
77
+ step: string;
78
+ timing: RuntimeLifecycleOperationTiming;
79
+ /**
80
+ * System-owned reason the operation started.
81
+ */
82
+ trigger: string;
83
+ }
84
+ /**
85
+ * Fixed timestamps for one observed operation revision.
86
+ */
87
+ export interface RuntimeLifecycleOperationTiming {
88
+ /**
89
+ * ISO 8601 timestamp when the current phase began.
90
+ */
91
+ phaseStartedAt: string;
92
+ /**
93
+ * ISO 8601 timestamp when the operation began.
94
+ */
95
+ startedAt: string;
96
+ /**
97
+ * ISO 8601 timestamp when this operation revision was recorded.
98
+ */
99
+ transitionedAt: string;
100
+ }
101
+ /**
102
+ * Lifecycle diagnostic event "runtime.lifecycle.progress_state". Experimental, ephemeral, observational-only state of runtime progress and the lifecycle operations that block it. Observation and delivery never control runtime or model behavior. Process death, diagnostic projection loss, transport loss, or serialization failure can prevent external delivery.
103
+ */
104
+ export interface RuntimeLifecycleProgressStateDiagnosticEvent {
105
+ data: RuntimeLifecycleProgressStateData;
106
+ /**
107
+ * ISO 8601 timestamp when the lifecycle diagnostic event was projected.
108
+ */
109
+ timestamp: string;
110
+ /**
111
+ * Type discriminator. Always "runtime.lifecycle.progress_state".
112
+ */
113
+ type: "runtime.lifecycle.progress_state";
114
+ }
115
+ /**
116
+ * Experimental, observational-only state of runtime progress and the lifecycle operations that block it. Observation and delivery never control runtime or model behavior. Process death, diagnostic projection loss, transport loss, or serialization failure can prevent external delivery.
117
+ */
118
+ export interface RuntimeLifecycleProgressStateData {
119
+ /**
120
+ * Complete dependency blocker set after this progress change.
121
+ */
122
+ blockers: RuntimeLifecycleBlocker[];
123
+ disposition?: RuntimeLifecycleDisposition;
124
+ /**
125
+ * Opaque identity for one session registry generation.
126
+ */
127
+ incarnationId: string;
128
+ /**
129
+ * Progress-owner-defined kind.
130
+ */
131
+ kind: string;
132
+ origin?: RuntimeLifecycleProgressOrigin;
133
+ /**
134
+ * Progress-owner-defined phase.
135
+ */
136
+ phase: string;
137
+ /**
138
+ * Opaque progress identifier, unique within the incarnation and kind.
139
+ */
140
+ progressId: string;
141
+ /**
142
+ * Orders changes to this progress record.
143
+ */
144
+ revision: number;
145
+ /**
146
+ * Session whose lifecycle owns this progress.
147
+ */
148
+ sessionId: string;
149
+ timing: RuntimeLifecycleProgressTiming;
150
+ }
151
+ /**
152
+ * Exact lifecycle operation awaited by a real dependency wait.
153
+ */
154
+ export interface RuntimeLifecycleBlocker {
155
+ /**
156
+ * Current phase of the awaited operation.
157
+ */
158
+ currentPhase: string;
159
+ /**
160
+ * Current production boundary of the awaited operation.
161
+ */
162
+ currentStep: string;
163
+ operationDisposition?: RuntimeLifecycleDisposition;
164
+ /**
165
+ * Opaque awaited operation identifier.
166
+ */
167
+ operationId: string;
168
+ /**
169
+ * Awaited operation revision observed by this blocker.
170
+ */
171
+ operationRevision: number;
172
+ /**
173
+ * System-owned capability required by the progress owner.
174
+ */
175
+ requirement: string;
176
+ /**
177
+ * System that owns the awaited operation.
178
+ */
179
+ system: string;
180
+ timing: RuntimeLifecycleBlockerTiming;
181
+ }
182
+ /**
183
+ * Timing of one real dependency wait.
184
+ */
185
+ export interface RuntimeLifecycleBlockerTiming {
186
+ /**
187
+ * ISO 8601 timestamp when this dependency began blocking progress.
188
+ */
189
+ blockingSince: string;
190
+ }
191
+ /**
192
+ * Immutable causal origin of a progress record with independent identity and settlement.
193
+ */
194
+ export interface RuntimeLifecycleProgressOrigin {
195
+ /**
196
+ * Kind of the originating progress record.
197
+ */
198
+ kind: string;
199
+ /**
200
+ * Identifier of the originating progress record.
201
+ */
202
+ progressId: string;
203
+ }
204
+ /**
205
+ * Fixed timestamps for one observed progress revision.
206
+ */
207
+ export interface RuntimeLifecycleProgressTiming {
208
+ /**
209
+ * ISO 8601 timestamp when the current phase began.
210
+ */
211
+ phaseStartedAt: string;
212
+ /**
213
+ * ISO 8601 timestamp when the progress record began.
214
+ */
215
+ startedAt: string;
216
+ /**
217
+ * ISO 8601 timestamp when this progress revision was recorded.
218
+ */
219
+ transitionedAt: string;
220
+ }
File without changes