@github/copilot-language-server 1.533.0 → 1.535.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.
@@ -291,6 +291,7 @@ class CopilotClient {
291
291
  /** Connection-level session filesystem config, set via constructor option. */
292
292
  sessionFsConfig = null;
293
293
  requestHandler = null;
294
+ builtinPluginDirectories = [];
294
295
  onGitHubTelemetry;
295
296
  clientGlobalHandlers = {};
296
297
  /**
@@ -419,6 +420,16 @@ class CopilotClient {
419
420
  if (options.sessionFs) {
420
421
  this.validateSessionFsConfig(options.sessionFs);
421
422
  }
423
+ if (options.builtinPluginDirectories) {
424
+ for (const path of options.builtinPluginDirectories) {
425
+ if (!(0, import_node_path.isAbsolute)(path)) {
426
+ throw new Error(
427
+ `builtinPluginDirectories must contain only absolute paths: ${path}`
428
+ );
429
+ }
430
+ }
431
+ this.builtinPluginDirectories = [...options.builtinPluginDirectories];
432
+ }
422
433
  if (conn.kind === "uri") {
423
434
  const { host, port } = this.parseCliUrl(conn.url);
424
435
  this.actualHost = host;
@@ -573,6 +584,16 @@ class CopilotClient {
573
584
  }
574
585
  await this.connectToServer();
575
586
  await this.verifyProtocolVersion();
587
+ if (this.builtinPluginDirectories.length > 0) {
588
+ try {
589
+ await this.connection.sendRequest("plugins.builtin.set", {
590
+ paths: this.builtinPluginDirectories
591
+ });
592
+ } catch (error) {
593
+ await this.forceStop();
594
+ throw error;
595
+ }
596
+ }
576
597
  if (this.sessionFsConfig) {
577
598
  await this.connection.sendRequest("sessionFs.setProvider", {
578
599
  initialCwd: this.sessionFsConfig.initialCwd,
@@ -1027,7 +1048,7 @@ class CopilotClient {
1027
1048
  this.onGetTraceContext,
1028
1049
  {
1029
1050
  mcpAuthHandler: config.onMcpAuthRequest,
1030
- managedSettingsEnabled: config.enableManagedSettings
1051
+ managedSettingsEnabled: config.enableManagedSettings === true || config.managedSettings !== void 0
1031
1052
  }
1032
1053
  );
1033
1054
  s.registerTools(config.tools);
@@ -1086,7 +1107,8 @@ class CopilotClient {
1086
1107
  overridesBuiltInTool: tool.overridesBuiltInTool,
1087
1108
  skipPermission: tool.skipPermission,
1088
1109
  defer: tool.defer,
1089
- metadata: tool.metadata
1110
+ metadata: tool.metadata,
1111
+ isTerminal: tool.isTerminal
1090
1112
  })),
1091
1113
  toolSearch: config.toolSearch,
1092
1114
  canvases: config.canvases?.map((canvas) => canvas.declaration),
@@ -1110,6 +1132,7 @@ class CopilotClient {
1110
1132
  models: config.models,
1111
1133
  enableSessionTelemetry: config.enableSessionTelemetry,
1112
1134
  enableCitations: config.enableCitations,
1135
+ enableFileChangeTracking: config.enableFileChangeTracking,
1113
1136
  sessionLimits: config.sessionLimits,
1114
1137
  modelCapabilities: config.modelCapabilities,
1115
1138
  largeOutput: toWireLargeOutput(config.largeOutput),
@@ -1154,7 +1177,8 @@ class CopilotClient {
1154
1177
  remoteSession: config.remoteSession,
1155
1178
  cloud: config.cloud,
1156
1179
  expAssignments: config.expAssignments,
1157
- enableManagedSettings: config.enableManagedSettings
1180
+ enableManagedSettings: config.enableManagedSettings,
1181
+ managedSettings: config.managedSettings
1158
1182
  });
1159
1183
  const {
1160
1184
  sessionId: returnedSessionId,
@@ -1232,7 +1256,7 @@ class CopilotClient {
1232
1256
  this.onGetTraceContext,
1233
1257
  {
1234
1258
  mcpAuthHandler: config.onMcpAuthRequest,
1235
- managedSettingsEnabled: config.enableManagedSettings
1259
+ managedSettingsEnabled: config.enableManagedSettings === true || config.managedSettings !== void 0
1236
1260
  }
1237
1261
  );
1238
1262
  session.registerTools(config.tools);
@@ -1296,6 +1320,7 @@ class CopilotClient {
1296
1320
  enableSessionTelemetry: config.enableSessionTelemetry,
1297
1321
  excludedBuiltinAgents: config.excludedBuiltinAgents,
1298
1322
  enableCitations: config.enableCitations,
1323
+ enableFileChangeTracking: config.enableFileChangeTracking,
1299
1324
  sessionLimits: config.sessionLimits,
1300
1325
  tools: config.tools?.map((tool) => ({
1301
1326
  name: tool.name,
@@ -1304,7 +1329,8 @@ class CopilotClient {
1304
1329
  overridesBuiltInTool: tool.overridesBuiltInTool,
1305
1330
  skipPermission: tool.skipPermission,
1306
1331
  defer: tool.defer,
1307
- metadata: tool.metadata
1332
+ metadata: tool.metadata,
1333
+ isTerminal: tool.isTerminal
1308
1334
  })),
1309
1335
  toolSearch: config.toolSearch,
1310
1336
  canvases: config.canvases?.map((canvas) => canvas.declaration),
@@ -1367,7 +1393,8 @@ class CopilotClient {
1367
1393
  remoteSession: config.remoteSession,
1368
1394
  openCanvases: config.openCanvases,
1369
1395
  expAssignments: config.expAssignments,
1370
- enableManagedSettings: config.enableManagedSettings
1396
+ enableManagedSettings: config.enableManagedSettings,
1397
+ managedSettings: config.managedSettings
1371
1398
  });
1372
1399
  const { workspacePath, capabilities, openCanvases } = response;
1373
1400
  session["_workspacePath"] = workspacePath;
@@ -18,6 +18,7 @@ var __copyProps = (to, from, except, desc) => {
18
18
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
19
  var factory_exports = {};
20
20
  __export(factory_exports, {
21
+ FACTORY_AGENT_OPTION_KEYS: () => FACTORY_AGENT_OPTION_KEYS,
21
22
  FactoryResumeError: () => FactoryResumeError,
22
23
  defineFactory: () => defineFactory,
23
24
  getFactoryDefinition: () => getFactoryDefinition,
@@ -33,6 +34,14 @@ const FACTORY_TERMINAL_STATUSES = /* @__PURE__ */ new Set([
33
34
  function isFactoryRunTerminal(status) {
34
35
  return FACTORY_TERMINAL_STATUSES.has(status);
35
36
  }
37
+ const FACTORY_AGENT_OPTION_KEYS = [
38
+ "label",
39
+ "schema",
40
+ "model",
41
+ "reasoningEffort",
42
+ "contextTier",
43
+ "agent"
44
+ ];
36
45
  class FactoryResumeError extends Error {
37
46
  constructor(code, message) {
38
47
  super(message);
@@ -116,6 +125,7 @@ function getFactoryDefinition(handle) {
116
125
  }
117
126
  // Annotate the CommonJS export names for ESM import in node:
118
127
  0 && (module.exports = {
128
+ FACTORY_AGENT_OPTION_KEYS,
119
129
  FactoryResumeError,
120
130
  defineFactory,
121
131
  getFactoryDefinition,
@@ -191,6 +191,12 @@ function createServerRpc(connection) {
191
191
  */
192
192
  disable: async (params) => connection.sendRequest("extensions.disable", params)
193
193
  },
194
+ /**
195
+ * Registers the calling SDK client as the per-entrypoint extension launch provider. Call before creating any sessions. When omitted, the runtime temporarily falls back to its built-in Node launcher for backward compatibility.
196
+ *
197
+ * @experimental
198
+ */
199
+ registerExtensionLaunchProvider: async () => connection.sendRequest("registerExtensionLaunchProvider", {}),
194
200
  /** @experimental */
195
201
  plugins: {
196
202
  /**
@@ -381,6 +387,15 @@ function createServerRpc(connection) {
381
387
  }
382
388
  },
383
389
  /** @experimental */
390
+ managedSettings: {
391
+ /**
392
+ * Discovers device-managed settings from production MDM and managed-file sources, validates them against the runtime-owned managed-settings schema, and returns the canonical JSON without requiring a session.
393
+ *
394
+ * @returns Validated device-managed settings discovered before a session exists.
395
+ */
396
+ read: async () => connection.sendRequest("managedSettings.read", {})
397
+ },
398
+ /** @experimental */
384
399
  runtime: {
385
400
  /**
386
401
  * Gracefully shuts down an SDK-owned runtime. The response is sent only after cleanup completes; callers may then terminate the owned runtime process.
@@ -857,9 +872,11 @@ function createSessionRpc(connection, sessionId) {
857
872
  /**
858
873
  * Lists durable factory runs for this session in creation order.
859
874
  *
860
- * @returns Factory runs in durable creation order.
875
+ * @param params Parameters for paging factory runs.
876
+ *
877
+ * @returns A page of factory runs in durable creation order.
861
878
  */
862
- listRuns: async () => connection.sendRequest("session.factory.listRuns", { sessionId }),
879
+ listRuns: async (params) => connection.sendRequest("session.factory.listRuns", { sessionId, ...params }),
863
880
  /**
864
881
  * Gets durable and live observability detail for one factory run.
865
882
  *
@@ -2623,6 +2640,11 @@ function registerClientSessionApiHandlers(connection, getHandlers) {
2623
2640
  });
2624
2641
  }
2625
2642
  function registerClientGlobalApiHandlers(connection, handlers) {
2643
+ connection.onRequest("extensionLaunchProvider.resolve", async (params) => {
2644
+ const handler = handlers.extensionLaunchProvider;
2645
+ if (!handler) throw new Error("No extensionLaunchProvider client-global handler registered");
2646
+ return handler.resolve(params);
2647
+ });
2626
2648
  connection.onRequest("llmInference.httpRequestStart", async (params) => {
2627
2649
  const handler = handlers.llmInference;
2628
2650
  if (!handler) throw new Error("No llmInference client-global handler registered");
@@ -34,6 +34,7 @@ __export(index_exports, {
34
34
  ToolSet: () => import_toolSet.ToolSet,
35
35
  approveAll: () => import_types2.approveAll,
36
36
  convertMcpCallToolResult: () => import_types2.convertMcpCallToolResult,
37
+ createAttributedPermissionResult: () => import_types2.createAttributedPermissionResult,
37
38
  createCanvas: () => import_canvas.createCanvas,
38
39
  createSessionFsAdapter: () => import_types2.createSessionFsAdapter,
39
40
  defineFactory: () => import_factory.defineFactory,
@@ -66,6 +67,7 @@ var import_types2 = require("./types.js");
66
67
  ToolSet,
67
68
  approveAll,
68
69
  convertMcpCallToolResult,
70
+ createAttributedPermissionResult,
69
71
  createCanvas,
70
72
  createSessionFsAdapter,
71
73
  defineFactory,
@@ -21,13 +21,29 @@ __export(session_exports, {
21
21
  CopilotSession: () => CopilotSession
22
22
  });
23
23
  module.exports = __toCommonJS(session_exports);
24
+ var import_node_async_hooks = require("node:async_hooks");
24
25
  var import_node = require("vscode-jsonrpc/node.js");
25
26
  var import_rpc = require("./generated/rpc.js");
26
27
  var import_canvas = require("./canvas.js");
27
28
  var import_telemetry = require("./telemetry.js");
29
+ var import_types = require("./types.js");
28
30
  var import_factory = require("./factory.js");
29
31
  function isFactoryResumeErrorCode(value) {
30
- return value === "not_found" || value === "non_resumable" || value === "already_active" || value === "reapproval_declined" || value === "no_approval_provider";
32
+ return value === "not_found" || value === "non_resumable" || value === "already_active" || value === "factory_already_running" || value === "factory_limits_invalid" || value === "factory_session_disposed" || value === "factory_storage_unavailable" || value === "factory_storage_corrupt";
33
+ }
34
+ function copyDefinedFactoryAgentOption(source, target, key) {
35
+ const value = source[key];
36
+ if (value !== void 0) {
37
+ target[key] = value;
38
+ }
39
+ }
40
+ const factoryExecutionStore = new import_node_async_hooks.AsyncLocalStorage();
41
+ function throwIfFactoryExecutionIsActive() {
42
+ if (factoryExecutionStore.getStore()?.active) {
43
+ throw new Error(
44
+ "factory.run and factory.resume are not allowed while a factory body is running on this call path."
45
+ );
46
+ }
31
47
  }
32
48
  function deserializeHookInput(raw) {
33
49
  if (!raw || typeof raw !== "object" || typeof raw.timestamp !== "number") {
@@ -148,7 +164,10 @@ class FactoryProgressBuffer {
148
164
  const lines = this.pending.splice(0);
149
165
  await this.flushTail;
150
166
  if (this.flushFailed) {
151
- throw this.flushError;
167
+ console.warn(
168
+ "Ignoring a background factory progress flush failure after the factory body settled",
169
+ this.flushError
170
+ );
152
171
  }
153
172
  if (lines.length > 0) {
154
173
  try {
@@ -179,9 +198,6 @@ class FactoryProgressBuffer {
179
198
  }
180
199
  }
181
200
  }
182
- function toPublicFactoryRunResult(envelope) {
183
- return envelope;
184
- }
185
201
  async function awaitFactoryOperation(operation, signal) {
186
202
  let rejectAbort;
187
203
  const abortPromise = new Promise((_resolve, reject) => {
@@ -261,6 +277,7 @@ class CopilotSession {
261
277
  */
262
278
  factory = {
263
279
  run: (async (nameOrHandle, options) => {
280
+ throwIfFactoryExecutionIsActive();
264
281
  const name = typeof nameOrHandle === "string" ? nameOrHandle : (0, import_factory.getFactoryDefinition)(nameOrHandle).meta.name;
265
282
  if (options?.resumeFromRunId !== void 0) {
266
283
  return this.factory.resume(options.resumeFromRunId, {
@@ -277,6 +294,7 @@ class CopilotSession {
277
294
  return this.settleFactoryRun(envelope);
278
295
  }),
279
296
  resume: (async (runId, options) => {
297
+ throwIfFactoryExecutionIsActive();
280
298
  let response;
281
299
  try {
282
300
  response = await this.rpc.factory.resume({
@@ -294,12 +312,12 @@ class CopilotSession {
294
312
  }
295
313
  return this.settleFactoryRun(response.run);
296
314
  }),
297
- getRun: async (runId) => toPublicFactoryRunResult(await this.rpc.factory.getRun({ runId })),
315
+ getRun: async (runId) => this.rpc.factory.getRun({ runId }),
298
316
  waitForRun: (runId, options) => this.waitForFactoryRun(runId, options?.signal),
299
- listRuns: async () => (await this.rpc.factory.listRuns()).runs,
317
+ listRuns: async () => (await this.rpc.factory.listRuns({})).runs,
300
318
  getRunDetail: (runId) => this.rpc.factory.getRunDetail({ runId }),
301
319
  getRunProgress: (runId, options = {}) => this.rpc.factory.getRunProgress({ runId, ...options }),
302
- cancel: async (runId) => toPublicFactoryRunResult(await this.rpc.factory.cancel({ runId }))
320
+ cancel: async (runId) => this.rpc.factory.cancel({ runId })
303
321
  };
304
322
  /**
305
323
  * Resolve a start/resume envelope into the terminal envelope callers expect.
@@ -310,7 +328,7 @@ class CopilotSession {
310
328
  */
311
329
  settleFactoryRun(envelope) {
312
330
  if ((0, import_factory.isFactoryRunTerminal)(envelope.status)) {
313
- return Promise.resolve(toPublicFactoryRunResult(envelope));
331
+ return Promise.resolve(envelope);
314
332
  }
315
333
  return this.waitForFactoryRun(envelope.runId);
316
334
  }
@@ -364,7 +382,7 @@ class CopilotSession {
364
382
  rereadRequested = false;
365
383
  const envelope = await this.rpc.factory.getRun({ runId });
366
384
  if ((0, import_factory.isFactoryRunTerminal)(envelope.status)) {
367
- finish(() => resolve(toPublicFactoryRunResult(envelope)));
385
+ finish(() => resolve(envelope));
368
386
  return;
369
387
  }
370
388
  } while (rereadRequested && !settled);
@@ -719,17 +737,22 @@ class CopilotSession {
719
737
  */
720
738
  async _executePermissionAndRespond(requestId, permissionRequest) {
721
739
  try {
722
- const result = await this.permissionHandler(permissionRequest, {
740
+ const handlerResult = await this.permissionHandler(permissionRequest, {
723
741
  sessionId: this.sessionId,
724
742
  managedSettingsEnabled: this.managedSettingsEnabled
725
743
  });
744
+ const isAttributed = (0, import_types.isAttributedPermissionResult)(handlerResult);
745
+ const result = isAttributed ? handlerResult.result : handlerResult;
746
+ const decisionContext = isAttributed ? handlerResult.decisionContext : void 0;
726
747
  if (result.kind === "no-result") {
727
748
  return;
728
749
  }
729
750
  if (this.disconnected) {
730
751
  return;
731
752
  }
732
- await this.rpc.permissions.handlePendingPermissionRequest({ requestId, result });
753
+ await this.rpc.permissions.handlePendingPermissionRequest(
754
+ decisionContext === void 0 ? { requestId, result } : { requestId, result, decisionContext }
755
+ );
733
756
  } catch (error) {
734
757
  if (this.disconnected) {
735
758
  return;
@@ -964,16 +987,16 @@ class CopilotSession {
964
987
  },
965
988
  agent: async (prompt, options = {}) => {
966
989
  await progress.flush();
990
+ const opts = {};
991
+ for (const key of import_factory.FACTORY_AGENT_OPTION_KEYS) {
992
+ copyDefinedFactoryAgentOption(options, opts, key);
993
+ }
967
994
  const response = await awaitFactoryOperation(
968
995
  () => self.rpc.factory.agent({
969
996
  factoryRunId: params.runId,
970
997
  executionToken: params.executionToken,
971
998
  prompt,
972
- opts: {
973
- label: options.label,
974
- schema: options.schema,
975
- model: options.model
976
- }
999
+ opts
977
1000
  }),
978
1001
  controller.signal
979
1002
  );
@@ -1021,7 +1044,14 @@ class CopilotSession {
1021
1044
  throw new Error("nested factories are not supported");
1022
1045
  }
1023
1046
  };
1024
- const result = await definition.run(context);
1047
+ const execution = { active: true };
1048
+ const result = await factoryExecutionStore.run(execution, async () => {
1049
+ try {
1050
+ return await definition.run(context);
1051
+ } finally {
1052
+ execution.active = false;
1053
+ }
1054
+ });
1025
1055
  if (result === void 0) {
1026
1056
  return {};
1027
1057
  }
@@ -27,9 +27,11 @@ __export(types_exports, {
27
27
  SessionFsSqliteTransactionFailure: () => import_sessionFsProvider2.SessionFsSqliteTransactionFailure,
28
28
  approveAll: () => approveAll,
29
29
  convertMcpCallToolResult: () => convertMcpCallToolResult,
30
+ createAttributedPermissionResult: () => createAttributedPermissionResult,
30
31
  createSessionFsAdapter: () => import_sessionFsProvider.createSessionFsAdapter,
31
32
  defaultJoinSessionPermissionHandler: () => defaultJoinSessionPermissionHandler,
32
- defineTool: () => defineTool
33
+ defineTool: () => defineTool,
34
+ isAttributedPermissionResult: () => isAttributedPermissionResult
33
35
  });
34
36
  module.exports = __toCommonJS(types_exports);
35
37
  var import_sessionFsProvider = require("./sessionFsProvider.js");
@@ -141,6 +143,13 @@ const SYSTEM_MESSAGE_SECTIONS = {
141
143
  description: "End-of-prompt instructions: parallel tool calling, persistence, task completion"
142
144
  }
143
145
  };
146
+ function isAttributedPermissionResult(result) {
147
+ return result.kind === "attributed";
148
+ }
149
+ function createAttributedPermissionResult(result, decisionContext) {
150
+ const inner = isAttributedPermissionResult(result) ? result.result : result;
151
+ return { kind: "attributed", result: inner, decisionContext };
152
+ }
144
153
  const approveAll = (request, invocation) => {
145
154
  if (invocation.managedSettingsEnabled) {
146
155
  throw new Error("approveAll cannot be used when managed settings are enabled");
@@ -167,7 +176,9 @@ const defaultJoinSessionPermissionHandler = () => ({
167
176
  SessionFsSqliteTransactionFailure,
168
177
  approveAll,
169
178
  convertMcpCallToolResult,
179
+ createAttributedPermissionResult,
170
180
  createSessionFsAdapter,
171
181
  defaultJoinSessionPermissionHandler,
172
- defineTool
182
+ defineTool,
183
+ isAttributedPermissionResult
173
184
  });
@@ -4,7 +4,7 @@
4
4
  "type": "git",
5
5
  "url": "https://github.com/github/copilot-sdk.git"
6
6
  },
7
- "version": "1.0.9",
7
+ "version": "1.0.11",
8
8
  "description": "TypeScript SDK for programmatic control of GitHub Copilot CLI via JSON-RPC",
9
9
  "main": "./dist/cjs/index.js",
10
10
  "types": "./dist/index.d.ts",
@@ -56,7 +56,7 @@
56
56
  "author": "GitHub",
57
57
  "license": "MIT",
58
58
  "dependencies": {
59
- "@github/copilot": "^1.0.78",
59
+ "@github/copilot": "^1.0.79",
60
60
  "koffi": "^3.1.0",
61
61
  "vscode-jsonrpc": "^8.2.1",
62
62
  "zod": "^4.3.6"
package/package.json CHANGED
@@ -11,7 +11,7 @@
11
11
  "url": "git+https://github.com/github/copilot-language-server-release.git"
12
12
  },
13
13
  "license": "MIT",
14
- "version": "1.533.0",
14
+ "version": "1.535.0",
15
15
  "bin": {
16
16
  "copilot-language-server": "../dist/language-server.js"
17
17
  },
@@ -42,19 +42,19 @@
42
42
  "vscode-languageserver-protocol": "^3.17.5"
43
43
  },
44
44
  "optionalDependencies": {
45
- "@github/copilot-language-server-win32-x64": "1.533.0",
46
- "@github/copilot-language-server-win32-arm64": "1.533.0",
47
- "@github/copilot-language-server-linux-x64": "1.533.0",
48
- "@github/copilot-language-server-linux-arm64": "1.533.0",
49
- "@github/copilot-language-server-darwin-x64": "1.533.0",
50
- "@github/copilot-language-server-darwin-arm64": "1.533.0",
51
- "@github/copilot-win32-x64": "1.0.78",
52
- "@github/copilot-win32-arm64": "1.0.78",
53
- "@github/copilot-linux-x64": "1.0.78",
54
- "@github/copilot-linux-arm64": "1.0.78",
55
- "@github/copilot-darwin-x64": "1.0.78",
56
- "@github/copilot-darwin-arm64": "1.0.78"
45
+ "@github/copilot-language-server-win32-x64": "1.535.0",
46
+ "@github/copilot-language-server-win32-arm64": "1.535.0",
47
+ "@github/copilot-language-server-linux-x64": "1.535.0",
48
+ "@github/copilot-language-server-linux-arm64": "1.535.0",
49
+ "@github/copilot-language-server-darwin-x64": "1.535.0",
50
+ "@github/copilot-language-server-darwin-arm64": "1.535.0",
51
+ "@github/copilot-win32-x64": "1.0.79",
52
+ "@github/copilot-win32-arm64": "1.0.79",
53
+ "@github/copilot-linux-x64": "1.0.79",
54
+ "@github/copilot-linux-arm64": "1.0.79",
55
+ "@github/copilot-darwin-x64": "1.0.79",
56
+ "@github/copilot-darwin-arm64": "1.0.79"
57
57
  },
58
58
  "buildType": "prod",
59
- "build": "99"
59
+ "build": "104"
60
60
  }