@github/copilot-sdk 1.0.11-preview.2 → 1.0.12-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.
@@ -217,9 +217,9 @@ function getBundledCliPath() {
217
217
  if (typeof import_meta.resolve === "function") {
218
218
  for (const packageName of packageNames) {
219
219
  try {
220
- const sdkUrl = import_meta.resolve(`${packageName}/sdk`);
221
- const sdkPath = (0, import_node_url.fileURLToPath)(sdkUrl);
222
- return (0, import_node_path.join)((0, import_node_path.dirname)((0, import_node_path.dirname)(sdkPath)), "index.js");
220
+ const packageEntryUrl = import_meta.resolve(packageName);
221
+ const packageEntryPath = (0, import_node_url.fileURLToPath)(packageEntryUrl);
222
+ return (0, import_node_path.join)((0, import_node_path.dirname)(packageEntryPath), "index.js");
223
223
  } catch {
224
224
  }
225
225
  }
@@ -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,
@@ -1098,7 +1119,7 @@ class CopilotClient {
1098
1119
  canvasProvider: config.canvasProvider,
1099
1120
  commands: config.commands?.map((cmd) => ({
1100
1121
  name: cmd.name,
1101
- description: cmd.description
1122
+ description: cmd.description ?? ""
1102
1123
  })),
1103
1124
  systemMessage: wireSystemMessage,
1104
1125
  availableTools: toolFilterOptions.availableTools,
@@ -1221,10 +1242,10 @@ class CopilotClient {
1221
1242
  return this.resumeSessionInternal(sessionId, config);
1222
1243
  }
1223
1244
  /** @internal */
1224
- async resumeSessionForExtension(sessionId, config, factories) {
1225
- return this.resumeSessionInternal(sessionId, config, factories);
1245
+ async resumeSessionForExtension(sessionId, config, factories, extensionOptions) {
1246
+ return this.resumeSessionInternal(sessionId, config, factories, extensionOptions);
1226
1247
  }
1227
- async resumeSessionInternal(sessionId, config, factories) {
1248
+ async resumeSessionInternal(sessionId, config, factories, extensionOptions) {
1228
1249
  if (!this.connection) {
1229
1250
  await this.start();
1230
1251
  }
@@ -1321,7 +1342,7 @@ class CopilotClient {
1321
1342
  canvasProvider: config.canvasProvider,
1322
1343
  commands: config.commands?.map((cmd) => ({
1323
1344
  name: cmd.name,
1324
- description: cmd.description
1345
+ description: cmd.description ?? ""
1325
1346
  })),
1326
1347
  provider: bearerWireProvider,
1327
1348
  capi: config.capi,
@@ -1373,12 +1394,30 @@ class CopilotClient {
1373
1394
  openCanvases: config.openCanvases,
1374
1395
  expAssignments: config.expAssignments,
1375
1396
  enableManagedSettings: config.enableManagedSettings,
1376
- managedSettings: config.managedSettings
1397
+ managedSettings: config.managedSettings,
1398
+ ...extensionOptions?.requestedEnvironmentVariables ? {
1399
+ requestedEnvironmentVariables: extensionOptions.requestedEnvironmentVariables
1400
+ } : {}
1377
1401
  });
1402
+ if (extensionOptions?.requestedEnvironmentVariables) {
1403
+ const requested = new Set(extensionOptions.requestedEnvironmentVariables);
1404
+ const { grantedEnvironmentVariables } = response;
1405
+ for (const [name, value] of Object.entries(grantedEnvironmentVariables ?? {})) {
1406
+ if (requested.has(name)) {
1407
+ process.env[name] = value;
1408
+ }
1409
+ }
1410
+ }
1378
1411
  const { workspacePath, capabilities, openCanvases } = response;
1379
1412
  session["_workspacePath"] = workspacePath;
1380
1413
  session.setCapabilities(capabilities);
1381
1414
  session.setOpenCanvases(openCanvases ?? []);
1415
+ if (config.mcpServers) {
1416
+ await this.connection.sendRequest("session.mcp.reloadWithConfig", {
1417
+ sessionId,
1418
+ config: { mcpServers: toWireMcpServers(config.mcpServers) }
1419
+ });
1420
+ }
1382
1421
  if (config.onMcpAuthRequest) {
1383
1422
  await this.connection.sendRequest("session.eventLog.registerInterest", {
1384
1423
  sessionId,
@@ -42,6 +42,7 @@ async function joinSession(config = {}) {
42
42
  const {
43
43
  extensionSdkPath: _stripped,
44
44
  factories,
45
+ requestedEnvironmentVariables,
45
46
  ...rest
46
47
  } = config;
47
48
  void _stripped;
@@ -52,7 +53,8 @@ async function joinSession(config = {}) {
52
53
  onPermissionRequest: config.onPermissionRequest ?? import_types.defaultJoinSessionPermissionHandler,
53
54
  suppressResumeEvent: config.suppressResumeEvent ?? true
54
55
  },
55
- factories
56
+ factories,
57
+ requestedEnvironmentVariables?.length ? { requestedEnvironmentVariables } : void 0
56
58
  );
57
59
  }
58
60
  // Annotate the CommonJS export names for ESM import in node:
@@ -43,7 +43,7 @@ function createServerRpc(connection) {
43
43
  /**
44
44
  * Lists Copilot models available to the authenticated user.
45
45
  *
46
- * @param params Optional GitHub token used to list models for a specific user instead of the global auth context.
46
+ * @param params Optional opaque account selection or compatibility GitHub token used to list models.
47
47
  *
48
48
  * @returns List of Copilot models available to the resolved user, including capabilities and billing metadata.
49
49
  */
@@ -69,9 +69,9 @@ function createServerRpc(connection) {
69
69
  /** @experimental */
70
70
  account: {
71
71
  /**
72
- * Gets Copilot quota usage for the authenticated user or supplied GitHub token.
72
+ * Gets Copilot quota usage for the current or opaquely selected authenticated user.
73
73
  *
74
- * @param params Optional GitHub token used to look up quota for a specific user instead of the global auth context.
74
+ * @param params Optional opaque account selection or compatibility GitHub token used to look up quota.
75
75
  *
76
76
  * @returns Quota usage snapshots for the resolved user, keyed by quota type.
77
77
  */
@@ -168,7 +168,15 @@ function createServerRpc(connection) {
168
168
  *
169
169
  * @returns MCP servers discovered from user, workspace, plugin, and built-in sources.
170
170
  */
171
- discover: async (params) => connection.sendRequest("mcp.discover", params)
171
+ discover: async (params) => connection.sendRequest("mcp.discover", params),
172
+ /**
173
+ * Requests a side-effect-free MCP install plan from a catalog candidate handle or a caller-supplied card. This host-implemented server method is available through SDK/TUI hosts; standalone and C-ABI runtimes whose host does not implement server-method dispatch return JSON-RPC MethodNotFound. A runtime with planning available returns a normalised plan and opaque single-use plan handle; a runtime without it returns the typed planning-unavailable result. A completed plan reports resource identity, provenance, eligible transport choices, the user-scope target, required typed values and secret placeholders, the policy result, the configuration changes installing would make, and whether a reload would be needed. Planning never writes configuration, stores a secret, or reloads MCP servers, so abandoning a plan needs no call and leaves nothing behind.
174
+ *
175
+ * @param params A side-effect-free request for an MCP install plan. Computing a plan never writes configuration, stores a secret, or reloads MCP servers.
176
+ *
177
+ * @returns Outcome of an mcp.planInstall call: either a normalised plan, or one typed refusal. Nothing is written in either case.
178
+ */
179
+ planInstall: async (params) => connection.sendRequest("mcp.planInstall", params)
172
180
  },
173
181
  /** @experimental */
174
182
  extensions: {
@@ -198,6 +206,17 @@ function createServerRpc(connection) {
198
206
  */
199
207
  registerExtensionLaunchProvider: async () => connection.sendRequest("registerExtensionLaunchProvider", {}),
200
208
  /** @experimental */
209
+ catalog: {
210
+ /**
211
+ * Requests a bounded catalog search. This host-implemented server method is available through SDK/TUI hosts; standalone and C-ABI runtimes whose host does not implement server-method dispatch return JSON-RPC MethodNotFound. A runtime with search available returns inert candidate summaries, each with an opaque single-use handle scoped to this runtime instance; a runtime without it returns the typed search-unavailable result. Public authorities may be searched anonymously, while an authority that requires credentials yields the typed authentication-required result. All returned text, URLs, and package metadata are untrusted external data and can never trigger instructions, tools, or installation. Read-only: nothing is installed, configured, or persisted.
212
+ *
213
+ * @param params A bounded catalog search. Both the query length and the result count are capped by the schema so a caller cannot request an unbounded scan.
214
+ *
215
+ * @returns Outcome of a catalog.search call: either bounded inert candidates, or one typed refusal. Never a partial success.
216
+ */
217
+ search: async (params) => connection.sendRequest("catalog.search", params)
218
+ },
219
+ /** @experimental */
201
220
  plugins: {
202
221
  /**
203
222
  * Lists plugins installed in user/global state.
@@ -246,6 +265,15 @@ function createServerRpc(connection) {
246
265
  */
247
266
  disable: async (params) => connection.sendRequest("plugins.disable", params),
248
267
  /** @experimental */
268
+ builtin: {
269
+ /**
270
+ * Replaces this server's trusted built-in plugin directories while no sessions are active.
271
+ *
272
+ * @param params Trusted built-in plugin directories to use for this runtime process.
273
+ */
274
+ set: async (params) => connection.sendRequest("plugins.builtin.set", params)
275
+ },
276
+ /** @experimental */
249
277
  marketplaces: {
250
278
  /**
251
279
  * Lists all registered marketplaces (defaults + user-added).
@@ -296,7 +324,13 @@ function createServerRpc(connection) {
296
324
  *
297
325
  * @param params Skill names to mark as disabled in global configuration, replacing any previous list.
298
326
  */
299
- setDisabledSkills: async (params) => connection.sendRequest("skills.config.setDisabledSkills", params)
327
+ setDisabledSkills: async (params) => connection.sendRequest("skills.config.setDisabledSkills", params),
328
+ /**
329
+ * Atomically adds or removes one skill from the disabled list.
330
+ *
331
+ * @param params Adds or removes a single skill from the global disabled list, leaving every other entry untouched.
332
+ */
333
+ setSkillDisabled: async (params) => connection.sendRequest("skills.config.setSkillDisabled", params)
300
334
  },
301
335
  /**
302
336
  * Discovers skills across global and project sources.
@@ -639,7 +673,7 @@ function createInternalServerRpc(connection) {
639
673
  /**
640
674
  * Performs the SDK server connection handshake and validates the optional connection token. Marked internal because this is JSON-RPC transport plumbing invoked automatically by an SDK client's own `connect()` wrapper, not a user-facing method. Stays internal as long as the SDK client owns the handshake; would only become public if the SDK ever exposed the raw schema surface to consumers without a connection wrapper.
641
675
  *
642
- * @param params Parameters for the `server.connect` handshake: an optional connection token and optional connection-level opt-ins (e.g. GitHub telemetry forwarding).
676
+ * @param params Connection-level opt-ins for the `server.connect` handshake. Transport authentication is consumed by the native protocol boundary before dispatch.
643
677
  *
644
678
  * @returns Handshake result reporting the server's protocol version and package version on success.
645
679
  *
@@ -982,6 +1016,8 @@ function createSessionRpc(connection, sessionId) {
982
1016
  * Sets the current agent interaction mode.
983
1017
  *
984
1018
  * @param params Agent interaction mode to apply to the session.
1019
+ *
1020
+ * @returns Outcome of a session mode change, including any model switch it triggered and follow-up the host must perform.
985
1021
  */
986
1022
  set: async (params) => connection.sendRequest("session.mode.set", { sessionId, ...params })
987
1023
  },
@@ -1384,6 +1420,12 @@ function createSessionRpc(connection, sessionId) {
1384
1420
  * Reloads MCP server connections for the session.
1385
1421
  */
1386
1422
  reload: async () => connection.sendRequest("session.mcp.reload", { sessionId }),
1423
+ /**
1424
+ * Releases any turns waiting on an in-flight MCP load without cancelling the load, letting the agent proceed while MCP servers finish connecting in the background. No-op when no MCP load is in flight or waiting turns were already released.
1425
+ *
1426
+ * @returns Result of moving in-flight MCP loading to the background.
1427
+ */
1428
+ moveLoadingToBackground: async () => connection.sendRequest("session.mcp.moveLoadingToBackground", { sessionId }),
1387
1429
  /**
1388
1430
  * Runs an MCP sampling inference on behalf of an MCP server.
1389
1431
  *
@@ -1464,6 +1506,14 @@ function createSessionRpc(connection, sessionId) {
1464
1506
  * @returns OAuth authorization URL the caller should open, or empty when cached tokens already authenticated the server.
1465
1507
  */
1466
1508
  login: async (params) => connection.sendRequest("session.mcp.oauth.login", { sessionId, ...params }),
1509
+ /**
1510
+ * Passively probes a configured remote MCP server to classify whether OAuth is required or a cached/override token is accepted. Does not start OAuth, emit pending OAuth requests, or mutate MCP connection state.
1511
+ *
1512
+ * @param params Remote MCP server name for a passive OAuth status probe.
1513
+ *
1514
+ * @returns Passive MCP OAuth probe result. `authenticated` means the server accepted the probe request while an OAuth-origin access token was attached; it does not prove the server required or independently validated that token. The probe does not make a second unauthenticated request. Failed is an expected probe-domain outcome; JSON-RPC errors are reserved for API-call failures.
1515
+ */
1516
+ probe: async (params) => connection.sendRequest("session.mcp.oauth.probe", { sessionId, ...params }),
1467
1517
  /**
1468
1518
  * Responds to a pending MCP OAuth authorization request by its request id.
1469
1519
  *
@@ -1646,6 +1696,30 @@ function createSessionRpc(connection, sessionId) {
1646
1696
  },
1647
1697
  /** @experimental */
1648
1698
  tools: {
1699
+ /**
1700
+ * Executes one tool from the session's currently offered tool set through the native invocation pipeline.
1701
+ *
1702
+ * @param params A tool name and arguments to execute through the session's native invocation pipeline.
1703
+ *
1704
+ * @returns Canonical result returned by a session tool.
1705
+ */
1706
+ execute: async (params) => connection.sendRequest("session.tools.execute", { sessionId, ...params }),
1707
+ /**
1708
+ * Returns the Rust-owned built-in tool descriptors used to construct the session's offered tool set.
1709
+ *
1710
+ * @param params Options controlling how Rust-owned built-in tool descriptors are materialized.
1711
+ *
1712
+ * @returns Rust-owned built-in tool descriptors for the session.
1713
+ */
1714
+ getBuiltinDescriptors: async (params) => connection.sendRequest("session.tools.getBuiltinDescriptors", { sessionId, ...params }),
1715
+ /**
1716
+ * Projects a completed task_complete tool call into its label-safe session event payload.
1717
+ *
1718
+ * @param params Task-completion tool arguments and final result used to build a label-safe session event payload.
1719
+ *
1720
+ * @returns Task completion notification with summary from the agent
1721
+ */
1722
+ taskCompleteEventData: async (params) => connection.sendRequest("session.tools.taskCompleteEventData", { sessionId, ...params }),
1649
1723
  /**
1650
1724
  * Provides the result for a pending external tool call.
1651
1725
  *
@@ -1666,6 +1740,14 @@ function createSessionRpc(connection, sessionId) {
1666
1740
  * @returns Current lightweight tool metadata snapshot for the session.
1667
1741
  */
1668
1742
  getCurrentMetadata: async () => connection.sendRequest("session.tools.getCurrentMetadata", { sessionId }),
1743
+ /**
1744
+ * Atomically replaces the complete externally implemented tool list supplied by the calling connection. Built-in, MCP/plugin, extension-discovered, subagent, and tools supplied by other connections remain unchanged.
1745
+ *
1746
+ * @param params Complete externally implemented tool list for the calling connection. An empty list removes every tool previously supplied by that connection.
1747
+ *
1748
+ * @returns Empty result after replacing the calling connection's externally implemented tools.
1749
+ */
1750
+ set: async (params) => connection.sendRequest("session.tools.set", { sessionId, ...params }),
1669
1751
  /**
1670
1752
  * Updates the current session's live subagent settings after user settings change. The persisted user settings remain the source of truth for future sessions.
1671
1753
  *
@@ -1748,7 +1830,7 @@ function createSessionRpc(connection, sessionId) {
1748
1830
  *
1749
1831
  * @param params Transient question to answer without adding it to conversation history.
1750
1832
  *
1751
- * @returns Transient answer generated from current conversation context.
1833
+ * @returns Completed transient query. Ordered chunks and the terminal outcome are also delivered through `ui.ephemeral_query` session events while it runs.
1752
1834
  */
1753
1835
  ephemeralQuery: async (params) => connection.sendRequest("session.ui.ephemeralQuery", { sessionId, ...params }),
1754
1836
  /**
@@ -1855,19 +1937,19 @@ function createSessionRpc(connection, sessionId) {
1855
1937
  */
1856
1938
  setApproveAll: async (params) => connection.sendRequest("session.permissions.setApproveAll", { sessionId, ...params }),
1857
1939
  /**
1858
- * Sets the allow-all permission mode for the session. Used by attach-mode clients (e.g. LocalRpcSession's `/allow-all` forwarder) to flip the target session's permission state. The `on` mode swaps in unrestricted path and URL managers and emits `session.permissions_changed` on transition; the `auto` mode keeps normal prompt paths active while attaching LLM safety recommendations. The result returns the authoritative post-mutation state so callers can update their local mirrors without racing the `session.permissions_changed` notification on the same wire.
1940
+ * Sets the permission mode for the session. `manual` follows the normal approval flow, `assisted` attaches LLM safety recommendations, and `allow-all` automatically approves permission requests. The result returns the authoritative post-mutation mode so callers can update local state without racing the `session.permissions_changed` notification.
1859
1941
  *
1860
- * @param params Allow-all mode to apply for the session.
1942
+ * @param params Permission mode to apply for the session.
1861
1943
  *
1862
- * @returns Indicates whether the operation succeeded and reports the post-mutation state.
1944
+ * @returns Indicates whether the requested permission mode was applied and reports the authoritative post-mutation mode.
1863
1945
  */
1864
- setAllowAll: async (params) => connection.sendRequest("session.permissions.setAllowAll", { sessionId, ...params }),
1946
+ setMode: async (params) => connection.sendRequest("session.permissions.setMode", { sessionId, ...params }),
1865
1947
  /**
1866
- * Returns the current allow-all permission mode for the session.
1948
+ * Returns the current permission mode for the session.
1867
1949
  *
1868
- * @returns Current allow-all permission mode.
1950
+ * @returns Current permission mode.
1869
1951
  */
1870
- getAllowAll: async () => connection.sendRequest("session.permissions.getAllowAll", { sessionId }),
1952
+ getMode: async () => connection.sendRequest("session.permissions.getMode", { sessionId }),
1871
1953
  /**
1872
1954
  * Adds or removes session-scoped or location-scoped permission rules.
1873
1955
  *
@@ -2385,6 +2467,90 @@ function createInternalSessionRpc(connection, sessionId) {
2385
2467
  */
2386
2468
  sendSystemNotification: async (params) => connection.sendRequest("session.sendSystemNotification", { sessionId, ...params }),
2387
2469
  /** @experimental */
2470
+ gitHubAuth: {
2471
+ /**
2472
+ * Gets the current authentication information for internal session hosts.
2473
+ *
2474
+ * @returns Current authentication information, or null when no authentication is active.
2475
+ */
2476
+ getCurrentAuthInfo: async () => connection.sendRequest("session.gitHubAuth.getCurrentAuthInfo", { sessionId }),
2477
+ /**
2478
+ * Gets all authentication accounts available to the internal session host.
2479
+ *
2480
+ * @returns Authentication accounts available to the internal session host.
2481
+ */
2482
+ getAllAuthAvailable: async () => connection.sendRequest("session.gitHubAuth.getAllAuthAvailable", { sessionId }),
2483
+ /**
2484
+ * Refreshes Copilot account metadata for the current authentication.
2485
+ *
2486
+ * @returns Current authentication information, or null when no authentication is active.
2487
+ */
2488
+ refreshCopilotUser: async () => connection.sendRequest("session.gitHubAuth.refreshCopilotUser", { sessionId }),
2489
+ /**
2490
+ * Logs in a GitHub user through the internal session host.
2491
+ *
2492
+ * @param params Internal GitHub login parameters.
2493
+ *
2494
+ * @returns Authentication credentials accepted only at native protocol ingress. Runtime outputs use credential-free `AuthIdentity` metadata.
2495
+ */
2496
+ login: async (params) => connection.sendRequest("session.gitHubAuth.login", { sessionId, ...params }),
2497
+ /**
2498
+ * Switches the session to another available authentication.
2499
+ *
2500
+ * @param params Parameters for switching the session's active authentication.
2501
+ */
2502
+ switchToAuth: async (params) => connection.sendRequest("session.gitHubAuth.switchToAuth", { sessionId, ...params }),
2503
+ /**
2504
+ * Logs out the session's current GitHub authentication.
2505
+ *
2506
+ * @returns Whether the current authentication was logged out.
2507
+ */
2508
+ logout: async () => connection.sendRequest("session.gitHubAuth.logout", { sessionId }),
2509
+ /**
2510
+ * Logs out a specific GitHub authentication.
2511
+ *
2512
+ * @param params Parameters identifying a GitHub authentication to log out.
2513
+ *
2514
+ * @returns Whether the requested authentication was logged out.
2515
+ */
2516
+ logoutUser: async (params) => connection.sendRequest("session.gitHubAuth.logoutUser", { sessionId, ...params }),
2517
+ /**
2518
+ * Gets validation errors from the most recent authentication attempt.
2519
+ *
2520
+ * @returns Validation errors from the most recent authentication attempt.
2521
+ */
2522
+ lastAuthErrors: async () => connection.sendRequest("session.gitHubAuth.lastAuthErrors", { sessionId })
2523
+ },
2524
+ /** @experimental */
2525
+ canvas: {
2526
+ /** @experimental */
2527
+ provider: {
2528
+ /**
2529
+ * Registers an internal canvas provider connection and its contributions.
2530
+ *
2531
+ * @param params Internal canvas provider registration parameters.
2532
+ */
2533
+ register: async (params) => connection.sendRequest("session.canvas.provider.register", { sessionId, ...params }),
2534
+ /**
2535
+ * Unregisters an internal canvas provider connection.
2536
+ *
2537
+ * @param params Internal canvas provider unregistration parameters.
2538
+ */
2539
+ unregister: async (params) => connection.sendRequest("session.canvas.provider.unregister", { sessionId, ...params })
2540
+ }
2541
+ },
2542
+ /** @experimental */
2543
+ model: {
2544
+ /**
2545
+ * Resolves and applies organization-managed and repository model overlays.
2546
+ *
2547
+ * @param params Managed, repository, and CLI model overrides to overlay onto the session at startup.
2548
+ *
2549
+ * @returns The model identifier active on the session after the switch.
2550
+ */
2551
+ applyStartupOverlay: async (params) => connection.sendRequest("session.model.applyStartupOverlay", { sessionId, ...params })
2552
+ },
2553
+ /** @experimental */
2388
2554
  mcp: {
2389
2555
  /**
2390
2556
  * Reloads MCP server connections for the session with an explicit host-provided configuration.
@@ -2397,7 +2563,7 @@ function createInternalSessionRpc(connection, sessionId) {
2397
2563
  /**
2398
2564
  * Configures the built-in GitHub MCP server for the session's current auth context.
2399
2565
  *
2400
- * @param params Opaque auth info used to configure GitHub MCP.
2566
+ * @param params Credential-free authentication identity used to configure GitHub MCP.
2401
2567
  *
2402
2568
  * @returns Result of configuring GitHub MCP.
2403
2569
  */
@@ -2416,6 +2582,17 @@ function createInternalSessionRpc(connection, sessionId) {
2416
2582
  unregisterExternalClient: async (params) => connection.sendRequest("session.mcp.unregisterExternalClient", { sessionId, ...params })
2417
2583
  },
2418
2584
  /** @experimental */
2585
+ commands: {
2586
+ /**
2587
+ * Finalizes persistence associated with a client-applied slash-command effect.
2588
+ *
2589
+ * @param params The pending slash-command invocation effect to finalize, plus whether the host applied or cancelled it.
2590
+ *
2591
+ * @returns Whether finalizing the invocation effect succeeded, and the failure reason when it did not.
2592
+ */
2593
+ finalizeInvocationEffect: async (params) => connection.sendRequest("session.commands.finalizeInvocationEffect", { sessionId, ...params })
2594
+ },
2595
+ /** @experimental */
2419
2596
  settings: {
2420
2597
  /**
2421
2598
  * Returns a redacted snapshot of session runtime settings, with secrets and raw feature flags excluded. Internal: the runtime settings shape is a runtime-internal surface and is deliberately kept out of the public SDK, because consumers should not depend on the runtime's internal settings layout. It remains callable in-process and is expected to be reworked as the runtime internals are consolidated.
package/dist/cjs/index.js CHANGED
@@ -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,
@@ -26,6 +26,7 @@ var import_node = require("vscode-jsonrpc/node.js");
26
26
  var import_rpc = require("./generated/rpc.js");
27
27
  var import_canvas = require("./canvas.js");
28
28
  var import_telemetry = require("./telemetry.js");
29
+ var import_types = require("./types.js");
29
30
  var import_factory = require("./factory.js");
30
31
  function isFactoryResumeErrorCode(value) {
31
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";
@@ -736,17 +737,22 @@ class CopilotSession {
736
737
  */
737
738
  async _executePermissionAndRespond(requestId, permissionRequest) {
738
739
  try {
739
- const result = await this.permissionHandler(permissionRequest, {
740
+ const handlerResult = await this.permissionHandler(permissionRequest, {
740
741
  sessionId: this.sessionId,
741
742
  managedSettingsEnabled: this.managedSettingsEnabled
742
743
  });
744
+ const isAttributed = (0, import_types.isAttributedPermissionResult)(handlerResult);
745
+ const result = isAttributed ? handlerResult.result : handlerResult;
746
+ const decisionContext = isAttributed ? handlerResult.decisionContext : void 0;
743
747
  if (result.kind === "no-result") {
744
748
  return;
745
749
  }
746
750
  if (this.disconnected) {
747
751
  return;
748
752
  }
749
- await this.rpc.permissions.handlePendingPermissionRequest({ requestId, result });
753
+ await this.rpc.permissions.handlePendingPermissionRequest(
754
+ decisionContext === void 0 ? { requestId, result } : { requestId, result, decisionContext }
755
+ );
750
756
  } catch (error) {
751
757
  if (this.disconnected) {
752
758
  return;
@@ -1168,7 +1174,13 @@ class CopilotSession {
1168
1174
  }
1169
1175
  try {
1170
1176
  const result = await this.elicitationHandler(context);
1171
- await this.rpc.ui.handlePendingElicitation({ requestId, result });
1177
+ await this.rpc.ui.handlePendingElicitation({
1178
+ requestId,
1179
+ result: {
1180
+ action: result.action,
1181
+ ...result.content ? { content: result.content } : {}
1182
+ }
1183
+ });
1172
1184
  } catch {
1173
1185
  try {
1174
1186
  await this.rpc.ui.handlePendingElicitation({
package/dist/cjs/types.js CHANGED
@@ -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
  });
package/dist/client.d.ts CHANGED
@@ -37,6 +37,7 @@ export declare class CopilotClient {
37
37
  /** Connection-level session filesystem config, set via constructor option. */
38
38
  private sessionFsConfig;
39
39
  private requestHandler;
40
+ private builtinPluginDirectories;
40
41
  private onGitHubTelemetry?;
41
42
  private clientGlobalHandlers;
42
43
  /**