@github/copilot-sdk 0.3.0 → 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/README.md CHANGED
@@ -32,13 +32,13 @@ import { CopilotClient, approveAll } from "@github/copilot-sdk";
32
32
  const client = new CopilotClient();
33
33
  await client.start();
34
34
 
35
- // Create a session (onPermissionRequest is required)
35
+ // Create a session (onPermissionRequest is optional; approveAll allows every tool)
36
36
  const session = await client.createSession({
37
37
  model: "gpt-5",
38
38
  onPermissionRequest: approveAll,
39
39
  });
40
40
 
41
- // Wait for response using typed event handlers
41
+ // Wait for the response using typed event handlers
42
42
  const done = new Promise<void>((resolve) => {
43
43
  session.on("assistant.message", (event) => {
44
44
  console.log(event.data.content);
@@ -79,17 +79,17 @@ new CopilotClient(options?: CopilotClientOptions)
79
79
 
80
80
  **Options:**
81
81
 
82
- - `cliPath?: string` - Path to CLI executable (default: uses COPILOT_CLI_PATH env var or bundled instance)
83
- - `cliArgs?: string[]` - Extra arguments prepended before SDK-managed flags (e.g. `["./dist-cli/index.js"]` when using `node`)
84
- - `cliUrl?: string` - URL of existing CLI server to connect to (e.g., `"localhost:8080"`, `"http://127.0.0.1:9000"`, or just `"8080"`). When provided, the client will not spawn a CLI process.
85
- - `port?: number` - Server port (default: 0 for random)
86
- - `useStdio?: boolean` - Use stdio transport instead of TCP (default: true)
87
- - `logLevel?: string` - Log level (default: "info")
88
- - `autoStart?: boolean` - Auto-start server (default: true)
82
+ - `connection?: RuntimeConnection` - How to connect to the Copilot runtime. Construct via the factory functions on `RuntimeConnection`:
83
+ - `RuntimeConnection.forStdio({ path?, args? })` (default) — spawn the runtime and communicate over its stdin/stdout.
84
+ - `RuntimeConnection.forTcp({ port?, connectionToken?, path?, args? })` — spawn the runtime as a TCP server.
85
+ - `RuntimeConnection.forUri(url, { connectionToken? })` — connect to an already-running runtime (mutually exclusive with `gitHubToken`/`useLoggedInUser`).
86
+ - `cwd?: string` - Working directory for the runtime process (default: current process cwd).
87
+ - `baseDirectory?: string` - Base directory for Copilot data (session state, config, etc.). Sets `COPILOT_HOME` on the spawned runtime. When not set, the runtime defaults to `~/.copilot`. Ignored when connecting via `RuntimeConnection.forUri`.
88
+ - `logLevel?: string` - Log level. When omitted, the runtime uses its own default (currently `"info"`).
89
89
  - `gitHubToken?: string` - GitHub token for authentication. When provided, takes priority over other auth methods.
90
- - `useLoggedInUser?: boolean` - Whether to use logged-in user for authentication (default: true, but false when `gitHubToken` is provided). Cannot be used with `cliUrl`.
91
- - `telemetry?: TelemetryConfig` - OpenTelemetry configuration for the CLI process. Providing this object enables telemetry — no separate flag needed. See [Telemetry](#telemetry) below.
92
- - `onGetTraceContext?: TraceContextProvider` - Advanced: callback for linking your application's own OpenTelemetry spans into the same distributed trace as the CLI's spans. Not needed for normal telemetry collection. See [Telemetry](#telemetry) below.
90
+ - `useLoggedInUser?: boolean` - Whether to use logged-in user for authentication (default: true, but false when `gitHubToken` is provided). Cannot be used with `RuntimeConnection.forUri`.
91
+ - `telemetry?: TelemetryConfig` - OpenTelemetry configuration for the runtime process. Providing this object enables telemetry — no separate flag needed. See [Telemetry](#telemetry) below.
92
+ - `onGetTraceContext?: TraceContextProvider` - Advanced: callback for linking your application's own OpenTelemetry spans into the same distributed trace as the runtime's spans. Not needed for normal telemetry collection. See [Telemetry](#telemetry) below.
93
93
 
94
94
  #### Methods
95
95
 
@@ -114,11 +114,11 @@ Create a new conversation session.
114
114
  - `sessionId?: string` - Custom session ID.
115
115
  - `model?: string` - Model to use ("gpt-5", "claude-sonnet-4.5", etc.). **Required when using custom provider.**
116
116
  - `reasoningEffort?: "low" | "medium" | "high" | "xhigh"` - Reasoning effort level for models that support it. Use `listModels()` to check which models support this option.
117
- - `tools?: Tool[]` - Custom tools exposed to the CLI
117
+ - `tools?: Tool[]` - Custom tools exposed to the CLI. Tools without `handler` are declaration-only and must be resolved via pending tool-call RPCs.
118
118
  - `systemMessage?: SystemMessageConfig` - System message customization (see below)
119
119
  - `infiniteSessions?: InfiniteSessionConfig` - Configure automatic context compaction (see below)
120
120
  - `provider?: ProviderConfig` - Custom API provider configuration (BYOK - Bring Your Own Key). See [Custom Providers](#custom-providers) section.
121
- - `onPermissionRequest: PermissionHandler` - **Required.** Handler called before each tool execution to approve or deny it. Use `approveAll` to allow everything, or provide a custom function for fine-grained control. See [Permission Handling](#permission-handling) section.
121
+ - `onPermissionRequest?: PermissionHandler` - Optional handler called before each tool execution to approve or deny it. When omitted, permission requests are emitted as events and left pending for manual resolution. Use `approveAll` to allow everything, or provide a custom function for fine-grained control. See [Permission Handling](#permission-handling) section.
122
122
  - `onUserInputRequest?: UserInputHandler` - Handler for user input requests from the agent. Enables the `ask_user` tool. See [User Input Requests](#user-input-requests) section.
123
123
  - `onElicitationRequest?: ElicitationHandler` - Handler for elicitation requests dispatched by the server. Enables this client to present form-based UI dialogs on behalf of the agent or other session participants. See [Elicitation Requests](#elicitation-requests) section.
124
124
  - `hooks?: SessionHooks` - Hook handlers for session lifecycle events. See [Session Hooks](#session-hooks) section.
@@ -127,14 +127,10 @@ Create a new conversation session.
127
127
 
128
128
  Resume an existing session. Returns the session with `workspacePath` populated if infinite sessions were enabled.
129
129
 
130
- ##### `ping(message?: string): Promise<{ message: string; timestamp: number }>`
130
+ ##### `ping(message?: string): Promise<{ message: string; timestamp: string }>`
131
131
 
132
132
  Ping the server to check connectivity.
133
133
 
134
- ##### `getState(): ConnectionState`
135
-
136
- Get current connection state.
137
-
138
134
  ##### `listSessions(filter?: SessionListFilter): Promise<SessionMetadata[]>`
139
135
 
140
136
  List all available sessions. Optionally filter by working directory context.
@@ -172,7 +168,7 @@ Request the TUI to switch to displaying the specified session. Only available in
172
168
  Subscribe to a specific session lifecycle event type. Returns an unsubscribe function.
173
169
 
174
170
  ```typescript
175
- const unsubscribe = client.on("session.foreground", (event) => {
171
+ const unsubscribe = client.onLifecycle("session.foreground", (event) => {
176
172
  console.log(`Session ${event.sessionId} is now in foreground`);
177
173
  });
178
174
  ```
@@ -182,7 +178,7 @@ const unsubscribe = client.on("session.foreground", (event) => {
182
178
  Subscribe to all session lifecycle events. Returns an unsubscribe function.
183
179
 
184
180
  ```typescript
185
- const unsubscribe = client.on((event) => {
181
+ const unsubscribe = client.onLifecycle((event) => {
186
182
  console.log(`${event.type}: ${event.sessionId}`);
187
183
  });
188
184
  ```
@@ -276,7 +272,7 @@ unsubscribe();
276
272
 
277
273
  Abort the currently processing message in this session.
278
274
 
279
- ##### `getMessages(): Promise<SessionEvent[]>`
275
+ ##### `getEvents(): Promise<SessionEvent[]>`
280
276
 
281
277
  Get all events/messages from this session.
282
278
 
@@ -414,7 +410,7 @@ Note: `assistant.message` and `assistant.reasoning` (final events) are always se
414
410
  ### Manual Server Control
415
411
 
416
412
  ```typescript
417
- const client = new CopilotClient({ autoStart: false });
413
+ const client = new CopilotClient({});
418
414
 
419
415
  // Start manually
420
416
  await client.start();
@@ -573,8 +569,8 @@ The SDK auto-injects environment context, tool instructions, and security guardr
573
569
  Use `mode: "customize"` to selectively override individual sections of the prompt while preserving the rest:
574
570
 
575
571
  ```typescript
576
- import { SYSTEM_PROMPT_SECTIONS } from "@github/copilot-sdk";
577
- import type { SectionOverride, SystemPromptSection } from "@github/copilot-sdk";
572
+ import { SYSTEM_MESSAGE_SECTIONS } from "@github/copilot-sdk";
573
+ import type { SectionOverride, SystemMessageSection } from "@github/copilot-sdk";
578
574
 
579
575
  const session = await client.createSession({
580
576
  model: "gpt-5",
@@ -597,7 +593,7 @@ const session = await client.createSession({
597
593
  });
598
594
  ```
599
595
 
600
- Available section IDs: `identity`, `tone`, `tool_efficiency`, `environment_context`, `code_change_rules`, `guidelines`, `safety`, `tool_instructions`, `custom_instructions`, `last_instructions`. Use the `SYSTEM_PROMPT_SECTIONS` constant for descriptions of each section.
596
+ Available section IDs: `identity`, `tone`, `tool_efficiency`, `environment_context`, `code_change_rules`, `guidelines`, `safety`, `tool_instructions`, `custom_instructions`, `runtime_instructions`, `last_instructions`. Use the `SYSTEM_MESSAGE_SECTIONS` constant for descriptions of each section.
601
597
 
602
598
  Each section override supports four actions:
603
599
 
@@ -801,7 +797,7 @@ Inbound trace context from the CLI is available on the `ToolInvocation` object p
801
797
 
802
798
  ## Permission Handling
803
799
 
804
- An `onPermissionRequest` handler is **required** whenever you create or resume a session. The handler is called before the agent executes each tool (file writes, shell commands, custom tools, etc.) and must return a decision.
800
+ An `onPermissionRequest` handler is optional when you create or resume a session. When provided, it is called before the agent executes each tool (file writes, shell commands, custom tools, etc.) and returns a decision. When omitted, permission requests are emitted as events and left pending for the consumer to resolve with the pending permission RPC.
805
801
 
806
802
  ### Approve All (simplest)
807
803
 
@@ -842,29 +838,32 @@ const session = await client.createSession({
842
838
  // request.fullCommandText — full shell command (for shell)
843
839
 
844
840
  if (request.kind === "shell") {
845
- // Deny shell commands
846
- return { kind: "denied-interactively-by-user" };
841
+ // Deny shell commands, optionally telling the model why
842
+ return { kind: "reject", feedback: "Shell commands are not allowed." };
847
843
  }
848
844
 
849
- return { kind: "approved" };
845
+ return { kind: "approve-once" };
850
846
  },
851
847
  });
852
848
  ```
853
849
 
854
850
  ### Permission Result Kinds
855
851
 
856
- | Kind | Meaning |
857
- | ----------------------------------------------------------- | ------------------------------------------------------------------------------------------- |
858
- | `"approved"` | Allow the tool to run |
859
- | `"denied-interactively-by-user"` | User explicitly denied the request |
860
- | `"denied-no-approval-rule-and-could-not-request-from-user"` | No approval rule matched and user could not be asked |
861
- | `"denied-by-rules"` | Denied by a policy rule |
862
- | `"denied-by-content-exclusion-policy"` | Denied due to a content exclusion policy |
863
- | `"no-result"` | Leave the request unanswered (only valid with protocol v1; rejected by protocol v2 servers) |
852
+ The handler must return one of the `PermissionDecision` shapes (or `{ kind: "no-result" }`). Approval scopes are present-tense — they describe the decision to apply, not the outcome reported back on session events:
853
+
854
+ | Kind | Meaning | Extra fields |
855
+ | ------------------------ | -------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------- |
856
+ | `"approve-once"` | Allow this single request | — |
857
+ | `"approve-for-session"` | Allow this request and remember the approval for the rest of the session | `approval?` (rule to remember), `domain?` (for URL approvals) |
858
+ | `"approve-for-location"` | Allow this request and persist the approval for this project location (git root or cwd) | `approval` (rule to persist), `locationKey` (location to persist under) |
859
+ | `"approve-permanently"` | Allow this request and persist the approval across sessions (currently used for URL domains) | `domain` (URL domain to approve) |
860
+ | `"reject"` | Deny the request | `feedback?` (optional string surfaced to the agent) |
861
+ | `"user-not-available"` | Deny the request because no user is available to confirm it | — |
862
+ | `"no-result"` | Leave the request unanswered (only valid with protocol v1; rejected by protocol v2 servers) | — |
864
863
 
865
864
  ### Resuming Sessions
866
865
 
867
- Pass `onPermissionRequest` when resuming a session too — it is required:
866
+ You may pass `onPermissionRequest` when resuming a session too:
868
867
 
869
868
  ```typescript
870
869
  const session = await client.resumeSession("session-id", {
@@ -958,7 +957,7 @@ const session = await client.createSession({
958
957
  };
959
958
  },
960
959
 
961
- // Called after each tool execution
960
+ // Called after each successful tool execution
962
961
  onPostToolUse: async (input, invocation) => {
963
962
  console.log(`Tool ${input.toolName} completed`);
964
963
  // Optionally modify the result or add context
@@ -967,6 +966,16 @@ const session = await client.createSession({
967
966
  };
968
967
  },
969
968
 
969
+ // Called after a tool execution whose result was "failure".
970
+ // onPostToolUse does NOT fire for failed tool calls — register this
971
+ // hook to observe them. Input includes `error` (the failure message
972
+ // extracted from the tool's result), not the full result object.
973
+ onPostToolUseFailure: async (input, invocation) => {
974
+ console.log(`Tool ${input.toolName} failed: ${input.error}`);
975
+ // Optionally append hidden guidance to the model.
976
+ return { additionalContext: "Suggest checking inputs and retrying." };
977
+ },
978
+
970
979
  // Called when user submits a prompt
971
980
  onUserPromptSubmitted: async (input, invocation) => {
972
981
  console.log(`User prompt: ${input.prompt}`);
@@ -1002,7 +1011,8 @@ const session = await client.createSession({
1002
1011
  **Available hooks:**
1003
1012
 
1004
1013
  - `onPreToolUse` - Intercept tool calls before execution. Can allow/deny or modify arguments.
1005
- - `onPostToolUse` - Process tool results after execution. Can modify results or add context.
1014
+ - `onPostToolUse` - Process tool results after **successful** execution. Can modify results or add context.
1015
+ - `onPostToolUseFailure` - Observe and append hidden guidance to the model after tool executions whose result was `"failure"`. Register this in addition to `onPostToolUse` to see failed tool calls.
1006
1016
  - `onUserPromptSubmitted` - Intercept user prompts. Can modify the prompt before processing.
1007
1017
  - `onSessionStart` - Run logic when a session starts or resumes.
1008
1018
  - `onSessionEnd` - Cleanup or logging when session ends.
@@ -1022,7 +1032,7 @@ try {
1022
1032
  ## Requirements
1023
1033
 
1024
1034
  - Node.js >= 18.0.0
1025
- - GitHub Copilot CLI installed and in PATH (or provide custom `cliPath`)
1035
+ - GitHub Copilot CLI installed and in PATH (or provide a custom `connection`)
1026
1036
 
1027
1037
  ## License
1028
1038
 
@@ -0,0 +1,126 @@
1
+ import type { CanvasJsonSchema, CanvasProviderCloseRequest, CanvasProviderInvokeActionRequest, CanvasProviderOpenRequest, CanvasProviderOpenResult } from "./generated/rpc.js";
2
+ export type { CanvasJsonSchema, CanvasHostContext, CanvasHostContextCapabilities, } from "./generated/rpc.js";
3
+ /**
4
+ * Extension-owned canvases declared via
5
+ * `joinSession({ canvases: [createCanvas({...})] })`.
6
+ *
7
+ * The runtime sends provider callbacks as `canvas.open`, `canvas.close`, and
8
+ * `canvas.action.invoke` JSON-RPC requests via the codegen client session API
9
+ * pipeline. The SDK routes those requests by `canvasId` to the in-process
10
+ * handlers bound by `createCanvas`. Re-opening with an existing `instanceId`
11
+ * is how the host focuses an existing panel; reload is a renderer-only concern.
12
+ *
13
+ * @experimental Canvas types are part of an experimental wire-protocol surface
14
+ * and may change or be removed in future SDK or CLI releases.
15
+ */
16
+ /**
17
+ * A single agent-callable action contributed by a canvas. The metadata
18
+ * (`name`, `description`, `inputSchema`) is serialized over the wire on
19
+ * `session.create` / `session.resume`; the `handler` closure is stripped
20
+ * before the declaration is sent and dispatched in-process by the SDK.
21
+ *
22
+ * Names MUST NOT start with `canvas.` — that prefix is reserved for
23
+ * lifecycle verbs.
24
+ *
25
+ * @experimental This type is part of an experimental wire-protocol surface
26
+ * and may change or be removed in future SDK or CLI releases.
27
+ */
28
+ export interface CanvasAction {
29
+ /** Action identifier, unique within the canvas. */
30
+ name: string;
31
+ /** Description shown to the model when picking an action. */
32
+ description?: string;
33
+ /** Optional JSON Schema for the action's `input` payload. */
34
+ inputSchema?: CanvasJsonSchema;
35
+ /** Required per-action dispatch handler. */
36
+ handler: (ctx: CanvasProviderInvokeActionRequest) => Promise<unknown> | unknown;
37
+ }
38
+ /**
39
+ * Declarative metadata for a single canvas, serialized over the wire on
40
+ * `session.create` / `session.resume`.
41
+ *
42
+ * @experimental This type is part of an experimental wire-protocol surface
43
+ * and may change or be removed in future SDK or CLI releases.
44
+ */
45
+ export interface CanvasDeclaration {
46
+ /** Canvas id, unique within the declaring connection. */
47
+ id: string;
48
+ /** Human-readable label shown in discovery and host UI chrome. */
49
+ displayName: string;
50
+ /** Short, single-sentence description shown to the agent in canvas catalogs. */
51
+ description: string;
52
+ /** Optional JSON Schema for the `input` payload accepted by `canvas.open`. */
53
+ inputSchema?: CanvasJsonSchema;
54
+ /** Agent-invocable actions exposed via `invoke_canvas_action`. */
55
+ actions?: Omit<CanvasAction, "handler">[];
56
+ }
57
+ /**
58
+ * Structured error returned from canvas handlers.
59
+ *
60
+ * @experimental This class is part of an experimental wire-protocol surface
61
+ * and may change or be removed in future SDK or CLI releases.
62
+ */
63
+ export declare class CanvasError extends Error {
64
+ readonly code: string;
65
+ constructor(code: string, message: string);
66
+ /** Default error when an action is declared but no `handler` is wired. */
67
+ static noHandler(): CanvasError;
68
+ }
69
+ /**
70
+ * Options accepted by {@link createCanvas}. Combines the declarative
71
+ * {@link CanvasDeclaration} fields with the in-process handler closures.
72
+ *
73
+ * @experimental This interface is part of an experimental wire-protocol surface
74
+ * and may change or be removed in future SDK or CLI releases.
75
+ */
76
+ export interface CanvasOptions {
77
+ /** @see CanvasDeclaration.id */
78
+ id: string;
79
+ /** @see CanvasDeclaration.displayName */
80
+ displayName: string;
81
+ /** @see CanvasDeclaration.description */
82
+ description: string;
83
+ /** @see CanvasDeclaration.inputSchema */
84
+ inputSchema?: CanvasJsonSchema;
85
+ /**
86
+ * Agent-invocable actions exposed via `invoke_canvas_action`. Each action
87
+ * carries its own required `handler`; the action's wire metadata
88
+ * (`name`, `description`, `inputSchema`) is what reaches the runtime.
89
+ */
90
+ actions?: CanvasAction[];
91
+ /** Required. Open a new canvas instance. */
92
+ open: (ctx: CanvasProviderOpenRequest) => Promise<CanvasProviderOpenResult> | CanvasProviderOpenResult;
93
+ /**
94
+ * Optional. Notified when a canvas instance is closed by the user, the
95
+ * agent, or the host. Fire-and-forget: the return value is ignored and
96
+ * errors are logged but not surfaced to the runtime.
97
+ */
98
+ onClose?: (ctx: CanvasProviderCloseRequest) => Promise<void> | void;
99
+ }
100
+ /** A registered canvas: declarative metadata + in-process handler closures.
101
+ *
102
+ * Node intentionally uses a per-canvas factory pattern (mirroring
103
+ * {@link https://github.com/github/copilot-sdk | `DefineTool`}'s co-location
104
+ * ergonomics) where other SDKs (Rust, Python, Go, .NET) expose a single
105
+ * `CanvasHandler` per session that switches on `canvasId`. Both shapes target
106
+ * the same JSON-RPC wire protocol; the divergence is API ergonomics only.
107
+ *
108
+ * @experimental This class is part of an experimental wire-protocol surface
109
+ * and may change or be removed in future SDK or CLI releases.
110
+ */
111
+ export declare class Canvas {
112
+ readonly declaration: CanvasDeclaration;
113
+ readonly open: NonNullable<CanvasOptions["open"]>;
114
+ readonly onClose?: CanvasOptions["onClose"];
115
+ }
116
+ /** Create a canvas declaration with bound in-process handlers.
117
+ *
118
+ * Node intentionally uses this per-canvas factory pattern (mirroring
119
+ * `DefineTool`'s co-location ergonomics) where other SDKs (Rust, Python, Go,
120
+ * .NET) expose a single `CanvasHandler` per session that switches on
121
+ * `canvasId`. Both shapes target the same JSON-RPC wire protocol.
122
+ *
123
+ * @experimental This function is part of an experimental wire-protocol surface
124
+ * and may change or be removed in future SDK or CLI releases.
125
+ */
126
+ export declare function createCanvas(options: CanvasOptions): Canvas;
package/dist/canvas.js ADDED
@@ -0,0 +1,49 @@
1
+ class CanvasError extends Error {
2
+ constructor(code, message) {
3
+ super(message);
4
+ this.code = code;
5
+ this.name = "CanvasError";
6
+ }
7
+ /** Default error when an action is declared but no `handler` is wired. */
8
+ static noHandler() {
9
+ return new CanvasError(
10
+ "canvas_action_no_handler",
11
+ "No handler implemented for this canvas action"
12
+ );
13
+ }
14
+ }
15
+ class Canvas {
16
+ declaration;
17
+ open;
18
+ onClose;
19
+ /** @internal */
20
+ actionHandlers;
21
+ /** @internal */
22
+ constructor(options) {
23
+ const actionHandlers = /* @__PURE__ */ new Map();
24
+ const wireActions = options.actions?.map(
25
+ ({ handler, ...wire }) => {
26
+ actionHandlers.set(wire.name, handler);
27
+ return wire;
28
+ }
29
+ );
30
+ this.declaration = {
31
+ id: options.id,
32
+ displayName: options.displayName,
33
+ description: options.description,
34
+ inputSchema: options.inputSchema,
35
+ actions: wireActions
36
+ };
37
+ this.open = options.open;
38
+ this.onClose = options.onClose;
39
+ this.actionHandlers = actionHandlers;
40
+ }
41
+ }
42
+ function createCanvas(options) {
43
+ return new Canvas(options);
44
+ }
45
+ export {
46
+ Canvas,
47
+ CanvasError,
48
+ createCanvas
49
+ };
@@ -0,0 +1,75 @@
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 canvas_exports = {};
20
+ __export(canvas_exports, {
21
+ Canvas: () => Canvas,
22
+ CanvasError: () => CanvasError,
23
+ createCanvas: () => createCanvas
24
+ });
25
+ module.exports = __toCommonJS(canvas_exports);
26
+ class CanvasError extends Error {
27
+ constructor(code, message) {
28
+ super(message);
29
+ this.code = code;
30
+ this.name = "CanvasError";
31
+ }
32
+ /** Default error when an action is declared but no `handler` is wired. */
33
+ static noHandler() {
34
+ return new CanvasError(
35
+ "canvas_action_no_handler",
36
+ "No handler implemented for this canvas action"
37
+ );
38
+ }
39
+ }
40
+ class Canvas {
41
+ declaration;
42
+ open;
43
+ onClose;
44
+ /** @internal */
45
+ actionHandlers;
46
+ /** @internal */
47
+ constructor(options) {
48
+ const actionHandlers = /* @__PURE__ */ new Map();
49
+ const wireActions = options.actions?.map(
50
+ ({ handler, ...wire }) => {
51
+ actionHandlers.set(wire.name, handler);
52
+ return wire;
53
+ }
54
+ );
55
+ this.declaration = {
56
+ id: options.id,
57
+ displayName: options.displayName,
58
+ description: options.description,
59
+ inputSchema: options.inputSchema,
60
+ actions: wireActions
61
+ };
62
+ this.open = options.open;
63
+ this.onClose = options.onClose;
64
+ this.actionHandlers = actionHandlers;
65
+ }
66
+ }
67
+ function createCanvas(options) {
68
+ return new Canvas(options);
69
+ }
70
+ // Annotate the CommonJS export names for ESM import in node:
71
+ 0 && (module.exports = {
72
+ Canvas,
73
+ CanvasError,
74
+ createCanvas
75
+ });