@github/copilot-sdk 1.0.0-beta.1 → 1.0.0-beta.10

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/cjs/index.js CHANGED
@@ -18,25 +18,40 @@ 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,
22
+ Canvas: () => import_canvas.Canvas,
23
+ CanvasError: () => import_canvas.CanvasError,
21
24
  CopilotClient: () => import_client.CopilotClient,
22
25
  CopilotSession: () => import_session.CopilotSession,
23
- SYSTEM_PROMPT_SECTIONS: () => import_types.SYSTEM_PROMPT_SECTIONS,
24
- approveAll: () => import_types.approveAll,
25
- convertMcpCallToolResult: () => import_types.convertMcpCallToolResult,
26
- createSessionFsAdapter: () => import_types.createSessionFsAdapter,
27
- defineTool: () => import_types.defineTool
26
+ RuntimeConnection: () => import_types.RuntimeConnection,
27
+ SYSTEM_MESSAGE_SECTIONS: () => import_types2.SYSTEM_MESSAGE_SECTIONS,
28
+ ToolSet: () => import_toolSet.ToolSet,
29
+ approveAll: () => import_types2.approveAll,
30
+ convertMcpCallToolResult: () => import_types2.convertMcpCallToolResult,
31
+ createCanvas: () => import_canvas.createCanvas,
32
+ createSessionFsAdapter: () => import_types2.createSessionFsAdapter,
33
+ defineTool: () => import_types2.defineTool
28
34
  });
29
35
  module.exports = __toCommonJS(index_exports);
30
36
  var import_client = require("./client.js");
31
- var import_session = require("./session.js");
32
37
  var import_types = require("./types.js");
38
+ var import_toolSet = require("./toolSet.js");
39
+ var import_session = require("./session.js");
40
+ var import_canvas = require("./canvas.js");
41
+ var import_types2 = require("./types.js");
33
42
  // Annotate the CommonJS export names for ESM import in node:
34
43
  0 && (module.exports = {
44
+ BuiltInTools,
45
+ Canvas,
46
+ CanvasError,
35
47
  CopilotClient,
36
48
  CopilotSession,
37
- SYSTEM_PROMPT_SECTIONS,
49
+ RuntimeConnection,
50
+ SYSTEM_MESSAGE_SECTIONS,
51
+ ToolSet,
38
52
  approveAll,
39
53
  convertMcpCallToolResult,
54
+ createCanvas,
40
55
  createSessionFsAdapter,
41
56
  defineTool
42
57
  });
@@ -18,14 +18,28 @@ var __copyProps = (to, from, except, desc) => {
18
18
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
19
  var session_exports = {};
20
20
  __export(session_exports, {
21
- CopilotSession: () => CopilotSession,
22
- NO_RESULT_PERMISSION_V2_ERROR: () => NO_RESULT_PERMISSION_V2_ERROR
21
+ CopilotSession: () => CopilotSession
23
22
  });
24
23
  module.exports = __toCommonJS(session_exports);
25
24
  var import_node = require("vscode-jsonrpc/node.js");
26
25
  var import_rpc = require("./generated/rpc.js");
26
+ var import_canvas = require("./canvas.js");
27
27
  var import_telemetry = require("./telemetry.js");
28
- const NO_RESULT_PERMISSION_V2_ERROR = "Permission handlers cannot return 'no-result' when connected to a protocol v2 server.";
28
+ function deserializeHookInput(raw) {
29
+ if (!raw || typeof raw !== "object" || typeof raw.timestamp !== "number") {
30
+ return raw;
31
+ }
32
+ const obj = raw;
33
+ const { cwd, ...rest } = obj;
34
+ return { ...rest, timestamp: new Date(obj.timestamp), workingDirectory: cwd };
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
+ }
29
43
  class CopilotSession {
30
44
  /**
31
45
  * Creates a new CopilotSession instance.
@@ -45,15 +59,19 @@ class CopilotSession {
45
59
  eventHandlers = /* @__PURE__ */ new Set();
46
60
  typedEventHandlers = /* @__PURE__ */ new Map();
47
61
  toolHandlers = /* @__PURE__ */ new Map();
62
+ canvases = /* @__PURE__ */ new Map();
48
63
  commandHandlers = /* @__PURE__ */ new Map();
49
64
  permissionHandler;
50
65
  userInputHandler;
51
66
  elicitationHandler;
67
+ exitPlanModeHandler;
68
+ autoModeSwitchHandler;
52
69
  hooks;
53
70
  transformCallbacks;
54
71
  _rpc = null;
55
72
  traceContextProvider;
56
73
  _capabilities = {};
74
+ openCanvasInstances = [];
57
75
  /** @internal Client session API handlers, populated by CopilotClient during create/resume. */
58
76
  clientSessionApis = {};
59
77
  /**
@@ -100,59 +118,22 @@ class CopilotSession {
100
118
  input: (message, options) => this._input(message, options)
101
119
  };
102
120
  }
103
- /**
104
- * Sends a message to this session and waits for the response.
105
- *
106
- * The message is processed asynchronously. Subscribe to events via {@link on}
107
- * to receive streaming responses and other session events.
108
- *
109
- * @param options - The message options including the prompt and optional attachments
110
- * @returns A promise that resolves with the message ID of the response
111
- * @throws Error if the session has been disconnected or the connection fails
112
- *
113
- * @example
114
- * ```typescript
115
- * const messageId = await session.send({
116
- * prompt: "Explain this code",
117
- * attachments: [{ type: "file", path: "./src/index.ts" }]
118
- * });
119
- * ```
120
- */
121
- async send(options) {
121
+ async send(optionsOrPrompt) {
122
+ const options = typeof optionsOrPrompt === "string" ? { prompt: optionsOrPrompt } : optionsOrPrompt;
122
123
  const response = await this.connection.sendRequest("session.send", {
123
124
  ...await (0, import_telemetry.getTraceContext)(this.traceContextProvider),
124
125
  sessionId: this.sessionId,
125
126
  prompt: options.prompt,
127
+ displayPrompt: options.displayPrompt,
126
128
  attachments: options.attachments,
127
129
  mode: options.mode,
130
+ agentMode: options.agentMode,
128
131
  requestHeaders: options.requestHeaders
129
132
  });
130
133
  return response.messageId;
131
134
  }
132
- /**
133
- * Sends a message to this session and waits until the session becomes idle.
134
- *
135
- * This is a convenience method that combines {@link send} with waiting for
136
- * the `session.idle` event. Use this when you want to block until the
137
- * assistant has finished processing the message.
138
- *
139
- * Events are still delivered to handlers registered via {@link on} while waiting.
140
- *
141
- * @param options - The message options including the prompt and optional attachments
142
- * @param timeout - Timeout in milliseconds (default: 60000). Controls how long to wait; does not abort in-flight agent work.
143
- * @returns A promise that resolves with the final assistant message when the session becomes idle,
144
- * or undefined if no assistant message was received
145
- * @throws Error if the timeout is reached before the session becomes idle
146
- * @throws Error if the session has been disconnected or the connection fails
147
- *
148
- * @example
149
- * ```typescript
150
- * // Send and wait for completion with default 60s timeout
151
- * const response = await session.sendAndWait({ prompt: "What is 2+2?" });
152
- * console.log(response?.data.content); // "4"
153
- * ```
154
- */
155
- async sendAndWait(options, timeout) {
135
+ async sendAndWait(optionsOrPrompt, timeout) {
136
+ const options = typeof optionsOrPrompt === "string" ? { prompt: optionsOrPrompt } : optionsOrPrompt;
156
137
  const effectiveTimeout = timeout ?? 6e4;
157
138
  let resolveIdle;
158
139
  let rejectWithError;
@@ -293,6 +274,25 @@ class CopilotSession {
293
274
  }
294
275
  } else if (event.type === "capabilities.changed") {
295
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);
296
296
  }
297
297
  }
298
298
  /**
@@ -395,8 +395,8 @@ class CopilotSession {
395
395
  /**
396
396
  * Registers custom tool handlers for this session.
397
397
  *
398
- * Tools allow the assistant to execute custom functions. When the assistant
399
- * invokes a tool, the corresponding handler is called with the tool arguments.
398
+ * Tools with handlers allow the assistant to execute custom functions automatically.
399
+ * Declaration-only tools are surfaced as events and left pending for the consumer.
400
400
  *
401
401
  * @param tools - An array of tool definitions with their handlers, or undefined to clear all tools
402
402
  * @internal This method is typically called internally when creating a session with tools.
@@ -407,7 +407,9 @@ class CopilotSession {
407
407
  return;
408
408
  }
409
409
  for (const tool of tools) {
410
- this.toolHandlers.set(tool.name, tool.handler);
410
+ if (tool.handler) {
411
+ this.toolHandlers.set(tool.name, tool.handler);
412
+ }
411
413
  }
412
414
  }
413
415
  /**
@@ -420,6 +422,61 @@ class CopilotSession {
420
422
  getToolHandler(name) {
421
423
  return this.toolHandlers.get(name);
422
424
  }
425
+ /**
426
+ * Registers canvas declarations and handlers for this session.
427
+ *
428
+ * @param canvases - Canvases created via `createCanvas`, or undefined to clear all canvases
429
+ * @internal Called by the SDK when creating/resuming a session with `canvases`.
430
+ */
431
+ registerCanvases(canvases) {
432
+ this.canvases.clear();
433
+ if (!canvases || canvases.length === 0) {
434
+ delete this.clientSessionApis.canvas;
435
+ return;
436
+ }
437
+ for (const canvas of canvases) {
438
+ this.canvases.set(canvas.declaration.id, canvas);
439
+ }
440
+ const self = this;
441
+ this.clientSessionApis.canvas = {
442
+ async open(params) {
443
+ const canvas = self.canvases.get(params.canvasId);
444
+ if (!canvas) throw new Error(`No canvas registered with id "${params.canvasId}"`);
445
+ try {
446
+ return await canvas.open(params) ?? {};
447
+ } catch (error) {
448
+ throw toCanvasRpcError(error);
449
+ }
450
+ },
451
+ async close(params) {
452
+ const canvas = self.canvases.get(params.canvasId);
453
+ if (!canvas) throw new Error(`No canvas registered with id "${params.canvasId}"`);
454
+ try {
455
+ if (canvas.onClose) {
456
+ await canvas.onClose(params);
457
+ }
458
+ } catch (error) {
459
+ throw toCanvasRpcError(error);
460
+ }
461
+ },
462
+ async invoke(params) {
463
+ const canvas = self.canvases.get(params.canvasId);
464
+ if (!canvas) throw new Error(`No canvas registered with id "${params.canvasId}"`);
465
+ const handler = canvas.actionHandlers.get(params.actionName);
466
+ if (!handler) {
467
+ throw new import_canvas.CanvasError(
468
+ "canvas_action_no_handler",
469
+ "No handler implemented for this canvas action"
470
+ );
471
+ }
472
+ try {
473
+ return await handler(params);
474
+ } catch (error) {
475
+ throw toCanvasRpcError(error);
476
+ }
477
+ }
478
+ };
479
+ }
423
480
  /**
424
481
  * Registers command handlers for this session.
425
482
  *
@@ -444,6 +501,24 @@ class CopilotSession {
444
501
  registerElicitationHandler(handler) {
445
502
  this.elicitationHandler = handler;
446
503
  }
504
+ /**
505
+ * Registers the exit-plan-mode handler for this session.
506
+ *
507
+ * @param handler - The handler to invoke when the server dispatches an exit-plan-mode request
508
+ * @internal This method is typically called internally when creating/resuming a session.
509
+ */
510
+ registerExitPlanModeHandler(handler) {
511
+ this.exitPlanModeHandler = handler;
512
+ }
513
+ /**
514
+ * Registers the auto-mode-switch handler for this session.
515
+ *
516
+ * @param handler - The handler to invoke when the server dispatches an auto-mode-switch request
517
+ * @internal This method is typically called internally when creating/resuming a session.
518
+ */
519
+ registerAutoModeSwitchHandler(handler) {
520
+ this.autoModeSwitchHandler = handler;
521
+ }
447
522
  /**
448
523
  * Handles an elicitation.requested broadcast event.
449
524
  * Invokes the registered handler and responds via handlePendingElicitation RPC.
@@ -469,6 +544,26 @@ class CopilotSession {
469
544
  }
470
545
  }
471
546
  }
547
+ /**
548
+ * Handles an exitPlanMode.request callback from the runtime.
549
+ * @internal
550
+ */
551
+ async _handleExitPlanModeRequest(request) {
552
+ if (!this.exitPlanModeHandler) {
553
+ return { approved: true };
554
+ }
555
+ return await this.exitPlanModeHandler(request, { sessionId: this.sessionId });
556
+ }
557
+ /**
558
+ * Handles an autoModeSwitch.request callback from the runtime.
559
+ * @internal
560
+ */
561
+ async _handleAutoModeSwitchRequest(request) {
562
+ if (!this.autoModeSwitchHandler) {
563
+ return "no";
564
+ }
565
+ return await this.autoModeSwitchHandler(request, { sessionId: this.sessionId });
566
+ }
472
567
  /**
473
568
  * Sets the host capabilities for this session.
474
569
  *
@@ -478,6 +573,24 @@ class CopilotSession {
478
573
  setCapabilities(capabilities) {
479
574
  this._capabilities = capabilities ?? {};
480
575
  }
576
+ /**
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.
581
+ */
582
+ get openCanvases() {
583
+ return [...this.openCanvasInstances];
584
+ }
585
+ /**
586
+ * Sets the open-canvas snapshot for this session.
587
+ *
588
+ * @param instances - The `openCanvases` array from the `session.resume` response.
589
+ * @internal This method is typically called internally when resuming a session.
590
+ */
591
+ setOpenCanvases(instances) {
592
+ this.openCanvasInstances = [...instances];
593
+ }
481
594
  assertElicitation() {
482
595
  if (!this._capabilities.ui?.elicitation) {
483
596
  throw new Error(
@@ -617,33 +730,6 @@ class CopilotSession {
617
730
  }
618
731
  return { sections: result };
619
732
  }
620
- /**
621
- * Handles a permission request in the v2 protocol format (synchronous RPC).
622
- * Used as a back-compat adapter when connected to a v2 server.
623
- *
624
- * @param request - The permission request data from the CLI
625
- * @returns A promise that resolves with the permission decision
626
- * @internal This method is for internal use by the SDK.
627
- */
628
- async _handlePermissionRequestV2(request) {
629
- if (!this.permissionHandler) {
630
- return { kind: "user-not-available" };
631
- }
632
- try {
633
- const result = await this.permissionHandler(request, {
634
- sessionId: this.sessionId
635
- });
636
- if (result.kind === "no-result") {
637
- throw new Error(NO_RESULT_PERMISSION_V2_ERROR);
638
- }
639
- return result;
640
- } catch (error) {
641
- if (error instanceof Error && error.message === NO_RESULT_PERMISSION_V2_ERROR) {
642
- throw error;
643
- }
644
- return { kind: "user-not-available" };
645
- }
646
- }
647
733
  /**
648
734
  * Handles a user input request from the Copilot CLI.
649
735
  *
@@ -676,9 +762,12 @@ class CopilotSession {
676
762
  if (!this.hooks) {
677
763
  return void 0;
678
764
  }
765
+ const normalized = deserializeHookInput(input);
679
766
  const handlerMap = {
680
767
  preToolUse: this.hooks.onPreToolUse,
768
+ preMcpToolCall: this.hooks.onPreMcpToolCall,
681
769
  postToolUse: this.hooks.onPostToolUse,
770
+ postToolUseFailure: this.hooks.onPostToolUseFailure,
682
771
  userPromptSubmitted: this.hooks.onUserPromptSubmitted,
683
772
  sessionStart: this.hooks.onSessionStart,
684
773
  sessionEnd: this.hooks.onSessionEnd,
@@ -689,7 +778,7 @@ class CopilotSession {
689
778
  return void 0;
690
779
  }
691
780
  try {
692
- const result = await handler(input, { sessionId: this.sessionId });
781
+ const result = await handler(normalized, { sessionId: this.sessionId });
693
782
  return result;
694
783
  } catch (_error) {
695
784
  return void 0;
@@ -706,7 +795,7 @@ class CopilotSession {
706
795
  *
707
796
  * @example
708
797
  * ```typescript
709
- * const events = await session.getMessages();
798
+ * const events = await session.getEvents();
710
799
  * for (const event of events) {
711
800
  * if (event.type === "assistant.message") {
712
801
  * console.log("Assistant:", event.data.content);
@@ -714,7 +803,7 @@ class CopilotSession {
714
803
  * }
715
804
  * ```
716
805
  */
717
- async getMessages() {
806
+ async getEvents() {
718
807
  const response = await this.connection.sendRequest("session.getMessages", {
719
808
  sessionId: this.sessionId
720
809
  });
@@ -749,18 +838,10 @@ class CopilotSession {
749
838
  this.typedEventHandlers.clear();
750
839
  this.toolHandlers.clear();
751
840
  this.permissionHandler = void 0;
752
- }
753
- /**
754
- * @deprecated Use {@link disconnect} instead. This method will be removed in a future release.
755
- *
756
- * Disconnects this session and releases all in-memory resources.
757
- * Session data on disk is preserved for later resumption.
758
- *
759
- * @returns A promise that resolves when the session is disconnected
760
- * @throws Error if the connection fails
761
- */
762
- async destroy() {
763
- return this.disconnect();
841
+ this.userInputHandler = void 0;
842
+ this.elicitationHandler = void 0;
843
+ this.exitPlanModeHandler = void 0;
844
+ this.autoModeSwitchHandler = void 0;
764
845
  }
765
846
  /** Enables `await using session = ...` syntax for automatic cleanup. */
766
847
  async [Symbol.asyncDispose]() {
@@ -846,8 +927,13 @@ function isToolResultObject(value) {
846
927
  ];
847
928
  return allowedResultTypes.includes(value.resultType);
848
929
  }
930
+ function toCanvasRpcError(error) {
931
+ if (error instanceof import_node.ResponseError) return error;
932
+ const code = error instanceof import_canvas.CanvasError ? error.code : "canvas_handler_error";
933
+ const message = error instanceof Error ? error.message : String(error);
934
+ return new import_node.ResponseError(import_node.ErrorCodes.InternalError, message, { code, message });
935
+ }
849
936
  // Annotate the CommonJS export names for ESM import in node:
850
937
  0 && (module.exports = {
851
- CopilotSession,
852
- NO_RESULT_PERMISSION_V2_ERROR
938
+ CopilotSession
853
939
  });
@@ -21,6 +21,18 @@ __export(sessionFsProvider_exports, {
21
21
  createSessionFsAdapter: () => createSessionFsAdapter
22
22
  });
23
23
  module.exports = __toCommonJS(sessionFsProvider_exports);
24
+ function normalizeSqliteParams(params) {
25
+ if (!params) {
26
+ return void 0;
27
+ }
28
+ const normalized = {};
29
+ for (const [key, value] of Object.entries(params)) {
30
+ if (value !== void 0) {
31
+ normalized[key] = value;
32
+ }
33
+ }
34
+ return normalized;
35
+ }
24
36
  function createSessionFsAdapter(provider) {
25
37
  return {
26
38
  readFile: async ({ path }) => {
@@ -107,6 +119,28 @@ function createSessionFsAdapter(provider) {
107
119
  } catch (err) {
108
120
  return toSessionFsError(err);
109
121
  }
122
+ },
123
+ // Unlike the FS methods above, SQLite methods let errors propagate to the JSON-RPC layer
124
+ // rather than catching and mapping via toSessionFsError. The FS error mapping is specifically
125
+ // for translating Node.js errno codes (e.g., ENOENT) into SessionFsError, which isn't
126
+ // meaningful for SQL errors. Letting exceptions propagate preserves the original error
127
+ // message in the JSON-RPC error response.
128
+ sqliteQuery: async ({ queryType, query, params: bindParams }) => {
129
+ if (!provider.sqlite) {
130
+ throw new Error("SQLite is not supported by this provider");
131
+ }
132
+ const result = await provider.sqlite.query(
133
+ queryType,
134
+ query,
135
+ normalizeSqliteParams(bindParams)
136
+ );
137
+ return result ?? { rows: [], columns: [], rowsAffected: 0 };
138
+ },
139
+ sqliteExists: async () => {
140
+ if (!provider.sqlite) {
141
+ throw new Error("SQLite is not supported by this provider");
142
+ }
143
+ return { exists: await provider.sqlite.exists() };
110
144
  }
111
145
  };
112
146
  }
@@ -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
+ });