@github/copilot-sdk 1.0.0-beta.8 → 1.0.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.
@@ -111,7 +111,11 @@ function createServerRpc(connection) {
111
111
  *
112
112
  * @param params MCP server names to disable for new sessions.
113
113
  */
114
- disable: async (params) => connection.sendRequest("mcp.config.disable", params)
114
+ disable: async (params) => connection.sendRequest("mcp.config.disable", params),
115
+ /**
116
+ * Drops this runtime process's in-memory MCP server-definition cache so the next MCP config read observes disk.
117
+ */
118
+ reload: async () => connection.sendRequest("mcp.config.reload", {})
115
119
  },
116
120
  /**
117
121
  * Discovers MCP servers from user, workspace, plugin, and builtin sources.
@@ -140,6 +144,20 @@ function createServerRpc(connection) {
140
144
  */
141
145
  discover: async (params) => connection.sendRequest("skills.discover", params)
142
146
  },
147
+ user: {
148
+ settings: {
149
+ /**
150
+ * Drops this runtime process's in-memory user settings cache so the next settings read observes disk.
151
+ */
152
+ reload: async () => connection.sendRequest("user.settings.reload", {})
153
+ }
154
+ },
155
+ runtime: {
156
+ /**
157
+ * Gracefully shuts down an SDK-owned runtime. The response is sent only after cleanup completes; callers may then terminate the owned runtime process.
158
+ */
159
+ shutdown: async () => connection.sendRequest("runtime.shutdown", {})
160
+ },
143
161
  sessionFs: {
144
162
  /**
145
163
  * Registers an SDK client as the session filesystem provider.
@@ -171,7 +189,7 @@ function createServerRpc(connection) {
171
189
  /**
172
190
  * Lists persisted sessions, optionally filtered by working-directory context.
173
191
  *
174
- * @param params Optional metadata-load limit and context filter applied to the returned sessions.
192
+ * @param params Optional metadata-load limit and filters applied to the returned sessions.
175
193
  *
176
194
  * @returns Persisted sessions matching the filter, ordered most-recently-modified first.
177
195
  */
@@ -302,6 +320,17 @@ function createServerRpc(connection) {
302
320
  * @returns Replace the manager-wide additional plugins. New session creations and subsequent hook reloads see the new set; already-running sessions keep their existing hook installation until the next reload.
303
321
  */
304
322
  setAdditionalPlugins: async (params) => connection.sendRequest("sessions.setAdditionalPlugins", params)
323
+ },
324
+ /** @experimental */
325
+ agentRegistry: {
326
+ /**
327
+ * Spawns a managed-server child with the supplied configuration and returns a discriminated-union result. The caller (typically the CLI controller) is responsible for attaching to the spawned child and sending any follow-up prompt. When the controller-local spawn gate is closed the server returns JSON-RPC MethodNotFound.
328
+ *
329
+ * @param params Inputs to spawn a managed-server child via the controller's spawn delegate.
330
+ *
331
+ * @returns Outcome of an agentRegistry.spawn call.
332
+ */
333
+ spawn: async (params) => connection.sendRequest("agentRegistry.spawn", params)
305
334
  }
306
335
  };
307
336
  }
@@ -398,27 +427,30 @@ function createSessionRpc(connection, sessionId) {
398
427
  * @param params Canvas close parameters.
399
428
  */
400
429
  close: async (params) => connection.sendRequest("session.canvas.close", { sessionId, ...params }),
401
- /**
402
- * Invokes an action on an open canvas instance.
403
- *
404
- * @param params Canvas action invocation parameters.
405
- *
406
- * @returns Canvas action invocation result.
407
- */
408
- invokeAction: async (params) => connection.sendRequest("session.canvas.invokeAction", { sessionId, ...params })
430
+ /** @experimental */
431
+ action: {
432
+ /**
433
+ * Invokes an action on an open canvas instance.
434
+ *
435
+ * @param params Canvas action invocation parameters.
436
+ *
437
+ * @returns Canvas action invocation result.
438
+ */
439
+ invoke: async (params) => connection.sendRequest("session.canvas.action.invoke", { sessionId, ...params })
440
+ }
409
441
  },
410
442
  /** @experimental */
411
443
  model: {
412
444
  /**
413
445
  * Gets the currently selected model for the session.
414
446
  *
415
- * @returns The currently selected model and reasoning effort for the session.
447
+ * @returns The currently selected model, reasoning effort, and context tier for the session. The context tier reflects `Session.getContextTier()`, restored from the session journal on resume.
416
448
  */
417
449
  getCurrent: async () => connection.sendRequest("session.model.getCurrent", { sessionId }),
418
450
  /**
419
451
  * Switches the session to a model and optional reasoning configuration.
420
452
  *
421
- * @param params Target model identifier and optional reasoning effort, summary, and capability overrides.
453
+ * @param params Target model identifier and optional reasoning effort, summary, capability overrides, and context tier.
422
454
  *
423
455
  * @returns The model identifier active on the session after the switch.
424
456
  */
@@ -430,7 +462,15 @@ function createSessionRpc(connection, sessionId) {
430
462
  *
431
463
  * @returns Update the session's reasoning effort without changing the selected model. Use `switchTo` instead when you also need to change the model. The runtime stores the effort on the session and applies it to subsequent turns.
432
464
  */
433
- setReasoningEffort: async (params) => connection.sendRequest("session.model.setReasoningEffort", { sessionId, ...params })
465
+ setReasoningEffort: async (params) => connection.sendRequest("session.model.setReasoningEffort", { sessionId, ...params }),
466
+ /**
467
+ * Lists models available to this session using its own auth and integration context. Connected hosts (CLI TUI, GitHub App) should call this through the session client so remote sessions return the remote CLI's available models rather than the caller's.
468
+ *
469
+ * @param params Optional listing options.
470
+ *
471
+ * @returns The list of models available to this session.
472
+ */
473
+ list: async (params) => connection.sendRequest("session.model.list", { sessionId, ...params })
434
474
  },
435
475
  /** @experimental */
436
476
  mode: {
@@ -884,7 +924,13 @@ function createSessionRpc(connection, sessionId) {
884
924
  /**
885
925
  * Reloads extension definitions and processes for the session.
886
926
  */
887
- reload: async () => connection.sendRequest("session.extensions.reload", { sessionId })
927
+ reload: async () => connection.sendRequest("session.extensions.reload", { sessionId }),
928
+ /**
929
+ * Push attachments into the next user-message turn from an extension. The host should surface them as composer pills and forward them via the next session.send call. Callable only by extension-owned connections.
930
+ *
931
+ * @param params Parameters for session.extensions.sendAttachmentsToMessage.
932
+ */
933
+ sendAttachmentsToMessage: async (params) => connection.sendRequest("session.extensions.sendAttachmentsToMessage", { sessionId, ...params })
888
934
  },
889
935
  /** @experimental */
890
936
  tools: {
@@ -901,7 +947,13 @@ function createSessionRpc(connection, sessionId) {
901
947
  *
902
948
  * @returns Resolve, build, and validate the runtime tool list for this session. Subagent sessions and consumer flows that need an initialized tool set before `send` invoke this. Default base-class implementation is a no-op for sessions that don't support tool validation.
903
949
  */
904
- initializeAndValidate: async () => connection.sendRequest("session.tools.initializeAndValidate", { sessionId })
950
+ initializeAndValidate: async () => connection.sendRequest("session.tools.initializeAndValidate", { sessionId }),
951
+ /**
952
+ * Returns lightweight metadata for the session's currently initialized tools.
953
+ *
954
+ * @returns Current lightweight tool metadata snapshot for the session.
955
+ */
956
+ getCurrentMetadata: async () => connection.sendRequest("session.tools.getCurrentMetadata", { sessionId })
905
957
  },
906
958
  /** @experimental */
907
959
  commands: {
@@ -1060,6 +1112,20 @@ function createSessionRpc(connection, sessionId) {
1060
1112
  * @returns Indicates whether the operation succeeded.
1061
1113
  */
1062
1114
  setApproveAll: async (params) => connection.sendRequest("session.permissions.setApproveAll", { sessionId, ...params }),
1115
+ /**
1116
+ * Enables or disables full allow-all permissions (tools, paths, and URLs) for the session. Used by attach-mode clients (e.g. LocalRpcSession's `/allow-all` forwarder) to flip the target session's permission state. Unlike `setApproveAll`, this swaps in the unrestricted path and URL managers and emits `session.permissions_changed` on transition. 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.
1117
+ *
1118
+ * @param params Whether to enable full allow-all permissions for the session.
1119
+ *
1120
+ * @returns Indicates whether the operation succeeded and reports the post-mutation state.
1121
+ */
1122
+ setAllowAll: async (params) => connection.sendRequest("session.permissions.setAllowAll", { sessionId, ...params }),
1123
+ /**
1124
+ * Returns whether full allow-all permissions are currently active for the session.
1125
+ *
1126
+ * @returns Current full allow-all permission state.
1127
+ */
1128
+ getAllowAll: async () => connection.sendRequest("session.permissions.getAllowAll", { sessionId }),
1063
1129
  /**
1064
1130
  * Adds or removes session-scoped or location-scoped permission rules.
1065
1131
  *
@@ -1476,10 +1542,10 @@ function registerClientSessionApiHandlers(connection, getHandlers) {
1476
1542
  if (!handler) throw new Error(`No canvas handler registered for session: ${params.sessionId}`);
1477
1543
  return handler.close(params);
1478
1544
  });
1479
- connection.onRequest("canvas.invokeAction", async (params) => {
1545
+ connection.onRequest("canvas.action.invoke", async (params) => {
1480
1546
  const handler = getHandlers(params.sessionId).canvas;
1481
1547
  if (!handler) throw new Error(`No canvas handler registered for session: ${params.sessionId}`);
1482
- return handler.invokeAction(params);
1548
+ return handler.invoke(params);
1483
1549
  });
1484
1550
  }
1485
1551
  // Annotate the CommonJS export names for ESM import in node:
package/dist/cjs/index.js CHANGED
@@ -18,12 +18,14 @@ var __copyProps = (to, from, except, desc) => {
18
18
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
19
  var index_exports = {};
20
20
  __export(index_exports, {
21
+ BuiltInTools: () => import_toolSet.BuiltInTools,
21
22
  Canvas: () => import_canvas.Canvas,
22
23
  CanvasError: () => import_canvas.CanvasError,
23
24
  CopilotClient: () => import_client.CopilotClient,
24
25
  CopilotSession: () => import_session.CopilotSession,
25
26
  RuntimeConnection: () => import_types.RuntimeConnection,
26
27
  SYSTEM_MESSAGE_SECTIONS: () => import_types2.SYSTEM_MESSAGE_SECTIONS,
28
+ ToolSet: () => import_toolSet.ToolSet,
27
29
  approveAll: () => import_types2.approveAll,
28
30
  convertMcpCallToolResult: () => import_types2.convertMcpCallToolResult,
29
31
  createCanvas: () => import_canvas.createCanvas,
@@ -33,17 +35,20 @@ __export(index_exports, {
33
35
  module.exports = __toCommonJS(index_exports);
34
36
  var import_client = require("./client.js");
35
37
  var import_types = require("./types.js");
38
+ var import_toolSet = require("./toolSet.js");
36
39
  var import_session = require("./session.js");
37
40
  var import_canvas = require("./canvas.js");
38
41
  var import_types2 = require("./types.js");
39
42
  // Annotate the CommonJS export names for ESM import in node:
40
43
  0 && (module.exports = {
44
+ BuiltInTools,
41
45
  Canvas,
42
46
  CanvasError,
43
47
  CopilotClient,
44
48
  CopilotSession,
45
49
  RuntimeConnection,
46
50
  SYSTEM_MESSAGE_SECTIONS,
51
+ ToolSet,
47
52
  approveAll,
48
53
  convertMcpCallToolResult,
49
54
  createCanvas,
@@ -33,6 +33,13 @@ function deserializeHookInput(raw) {
33
33
  const { cwd, ...rest } = obj;
34
34
  return { ...rest, timestamp: new Date(obj.timestamp), workingDirectory: cwd };
35
35
  }
36
+ function isOpenCanvasInstance(value) {
37
+ if (!value || typeof value !== "object") {
38
+ return false;
39
+ }
40
+ const instance = value;
41
+ return typeof instance.instanceId === "string" && instance.instanceId.length > 0 && typeof instance.extensionId === "string" && instance.extensionId.length > 0 && typeof instance.canvasId === "string" && instance.canvasId.length > 0 && typeof instance.reopen === "boolean" && (instance.availability === "ready" || instance.availability === "stale");
42
+ }
36
43
  class CopilotSession {
37
44
  /**
38
45
  * Creates a new CopilotSession instance.
@@ -117,8 +124,10 @@ class CopilotSession {
117
124
  ...await (0, import_telemetry.getTraceContext)(this.traceContextProvider),
118
125
  sessionId: this.sessionId,
119
126
  prompt: options.prompt,
127
+ displayPrompt: options.displayPrompt,
120
128
  attachments: options.attachments,
121
129
  mode: options.mode,
130
+ agentMode: options.agentMode,
122
131
  requestHeaders: options.requestHeaders
123
132
  });
124
133
  return response.messageId;
@@ -265,6 +274,25 @@ class CopilotSession {
265
274
  }
266
275
  } else if (event.type === "capabilities.changed") {
267
276
  this._capabilities = { ...this._capabilities, ...event.data };
277
+ } else if (event.type === "session.canvas.opened") {
278
+ this.upsertOpenCanvasFromEvent(event.data);
279
+ }
280
+ }
281
+ upsertOpenCanvasFromEvent(data) {
282
+ if (!isOpenCanvasInstance(data)) {
283
+ console.warn("failed to deserialize session.canvas.opened payload");
284
+ return;
285
+ }
286
+ this.upsertOpenCanvas(data);
287
+ }
288
+ upsertOpenCanvas(instance) {
289
+ const index = this.openCanvasInstances.findIndex(
290
+ (open) => open.instanceId === instance.instanceId
291
+ );
292
+ if (index >= 0) {
293
+ this.openCanvasInstances[index] = instance;
294
+ } else {
295
+ this.openCanvasInstances.push(instance);
268
296
  }
269
297
  }
270
298
  /**
@@ -431,7 +459,7 @@ class CopilotSession {
431
459
  throw toCanvasRpcError(error);
432
460
  }
433
461
  },
434
- async invokeAction(params) {
462
+ async invoke(params) {
435
463
  const canvas = self.canvases.get(params.canvasId);
436
464
  if (!canvas) throw new Error(`No canvas registered with id "${params.canvasId}"`);
437
465
  const handler = canvas.actionHandlers.get(params.actionName);
@@ -546,10 +574,10 @@ class CopilotSession {
546
574
  this._capabilities = capabilities ?? {};
547
575
  }
548
576
  /**
549
- * Snapshot of canvas instances that were already open when the session was
550
- * resumed. Populated from the `session.resume` response; empty for freshly
551
- * created sessions. Returns a defensive copy — mutating the returned array
552
- * has no effect on the session.
577
+ * Snapshot of canvas instances currently known to be open for this session.
578
+ * Populated from the `session.resume` response and live `session.canvas.opened`
579
+ * events. Returns a defensive copy — mutating the returned array has no effect
580
+ * on the session.
553
581
  */
554
582
  get openCanvases() {
555
583
  return [...this.openCanvasInstances];
@@ -739,6 +767,7 @@ class CopilotSession {
739
767
  preToolUse: this.hooks.onPreToolUse,
740
768
  preMcpToolCall: this.hooks.onPreMcpToolCall,
741
769
  postToolUse: this.hooks.onPostToolUse,
770
+ postToolUseFailure: this.hooks.onPostToolUseFailure,
742
771
  userPromptSubmitted: this.hooks.onUserPromptSubmitted,
743
772
  sessionStart: this.hooks.onSessionStart,
744
773
  sessionEnd: this.hooks.onSessionEnd,
@@ -0,0 +1,107 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+ var toolSet_exports = {};
20
+ __export(toolSet_exports, {
21
+ BuiltInTools: () => BuiltInTools,
22
+ ToolSet: () => ToolSet
23
+ });
24
+ module.exports = __toCommonJS(toolSet_exports);
25
+ const VALID_TOOL_NAME = /^[a-zA-Z0-9_-]+$/;
26
+ function validateName(kind, name) {
27
+ if (name === "*") {
28
+ return;
29
+ }
30
+ if (!VALID_TOOL_NAME.test(name)) {
31
+ throw new Error(
32
+ `Invalid ${kind} tool name '${name}': tool names must match /^[a-zA-Z0-9_-]+$/ or be the wildcard '*'.`
33
+ );
34
+ }
35
+ }
36
+ class ToolSet {
37
+ items = [];
38
+ addBuiltIn(nameOrNames) {
39
+ const names = typeof nameOrNames === "string" ? [nameOrNames] : nameOrNames;
40
+ for (const name of names) {
41
+ validateName("builtin", name);
42
+ this.items.push(`builtin:${name}`);
43
+ }
44
+ return this;
45
+ }
46
+ /**
47
+ * Adds a custom tool pattern. Matches tools registered via the SDK's
48
+ * `tools` option or via custom agents.
49
+ *
50
+ * @param name A specific custom tool name or `"*"` to match all custom tools.
51
+ */
52
+ addCustom(name) {
53
+ validateName("custom", name);
54
+ this.items.push(`custom:${name}`);
55
+ return this;
56
+ }
57
+ /**
58
+ * Adds an MCP tool pattern. Matches tools advertised by any configured
59
+ * MCP server.
60
+ *
61
+ * @param toolName The runtime's canonical wire name for the MCP tool
62
+ * (e.g. `"github-list_issues"`), or `"*"` to match all MCP tools from
63
+ * any server.
64
+ */
65
+ addMcp(toolName) {
66
+ validateName("mcp", toolName);
67
+ this.items.push(`mcp:${toolName}`);
68
+ return this;
69
+ }
70
+ /**
71
+ * Returns a defensive copy of the accumulated filter strings, suitable for
72
+ * passing as {@link SessionConfigBase.availableTools}.
73
+ */
74
+ toArray() {
75
+ return [...this.items];
76
+ }
77
+ }
78
+ const BuiltInTools = {
79
+ /**
80
+ * Built-in tools that operate only within the bounds of a single session —
81
+ * no host filesystem access outside the session, no cross-session state,
82
+ * no host environment access, no network. Safe to enable in `Mode = "empty"`
83
+ * scenarios (e.g. multi-tenant servers) without leaking host capabilities.
84
+ *
85
+ * **Contract:** tools in this set MUST NOT be extended (even behind options
86
+ * or args) to read or write state outside the session boundary. Adding
87
+ * cross-session or host-state behavior to one of these tools is a
88
+ * breaking change that requires removing it from this set.
89
+ */
90
+ Isolated: [
91
+ "ask_user",
92
+ "task_complete",
93
+ "exit_plan_mode",
94
+ "task",
95
+ "read_agent",
96
+ "write_agent",
97
+ "list_agents",
98
+ "send_inbox",
99
+ "context_board",
100
+ "skill"
101
+ ]
102
+ };
103
+ // Annotate the CommonJS export names for ESM import in node:
104
+ 0 && (module.exports = {
105
+ BuiltInTools,
106
+ ToolSet
107
+ });
package/dist/client.d.ts CHANGED
@@ -190,34 +190,26 @@ export declare class CopilotClient {
190
190
  * ```
191
191
  */
192
192
  forceStop(): Promise<void>;
193
+ /** Mode-specific defaults spread under the caller's config (app values win). */
194
+ private configDefaultsForMode;
193
195
  /**
194
- * Creates a new conversation session with the Copilot CLI.
195
- *
196
- * Sessions maintain conversation state, handle events, and manage tool execution.
197
- * If the client is not connected, this method automatically starts the connection.
198
- *
199
- * @param config - Optional configuration for the session
200
- * @returns A promise that resolves with the created session
201
- * @throws Error if the client fails to start
202
- *
203
- * @example
204
- * ```typescript
205
- * // Basic session
206
- * const session = await client.createSession({ onPermissionRequest: approveAll });
196
+ * Returns the systemMessage config to use, adjusted for the current mode.
197
+ * In empty mode we ensure the environment_context section is removed
198
+ * unless the app has already taken control of it. `append` (and
199
+ * unspecified) mode is promoted to `customize` so we can also strip
200
+ * environment_context; the caller's `content` is preserved verbatim
201
+ * because the runtime appends it as additional instructions in both
202
+ * customize and append modes.
203
+ */
204
+ private getSystemMessageConfigForMode;
205
+ /**
206
+ * Mode-specific options applied via session.options.update after create/resume.
207
207
  *
208
- * // Session with model and tools
209
- * const session = await client.createSession({
210
- * onPermissionRequest: approveAll,
211
- * model: "gpt-4",
212
- * tools: [{
213
- * name: "get_weather",
214
- * description: "Get weather for a location",
215
- * parameters: { type: "object", properties: { location: { type: "string" } } },
216
- * handler: async (args) => ({ temperature: 72 })
217
- * }]
218
- * });
219
- * ```
208
+ * In empty mode, defaults the four overridable feature flags to safe values
209
+ * (caller values from `config` win). `installedPlugins=[]` is unconditional
210
+ * in empty mode — apps that need custom plugins should switch modes.
220
211
  */
212
+ private updateSessionOptionsForMode;
221
213
  createSession(config: SessionConfig): Promise<CopilotSession>;
222
214
  /**
223
215
  * Resumes an existing conversation session by its ID.