@github/copilot-sdk 1.0.0-beta.4 → 1.0.0-beta.6

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/index.d.ts CHANGED
@@ -4,6 +4,8 @@
4
4
  * JSON-RPC based SDK for programmatic control of GitHub Copilot CLI
5
5
  */
6
6
  export { CopilotClient } from "./client.js";
7
+ export { RuntimeConnection } from "./types.js";
7
8
  export { CopilotSession, type AssistantMessageEvent } from "./session.js";
8
9
  export { defineTool, approveAll, convertMcpCallToolResult, createSessionFsAdapter, SYSTEM_PROMPT_SECTIONS, } from "./types.js";
9
- export type { CommandContext, CommandDefinition, CommandHandler, AutoModeSwitchHandler, AutoModeSwitchRequest, AutoModeSwitchResponse, ConnectionState, CopilotClientOptions, CustomAgentConfig, ElicitationFieldValue, ElicitationHandler, ElicitationParams, ElicitationContext, ElicitationResult, ElicitationSchema, ElicitationSchemaField, ExitPlanModeHandler, ExitPlanModeRequest, ExitPlanModeResult, ForegroundSessionInfo, GetAuthStatusResponse, GetStatusResponse, InfiniteSessionConfig, InputOptions, MCPStdioServerConfig, MCPHTTPServerConfig, MCPServerConfig, DefaultAgentConfig, MessageOptions, ModelBilling, ModelCapabilities, ModelCapabilitiesOverride, ModelInfo, ModelPolicy, PermissionHandler, PermissionRequest, PermissionRequestResult, ProviderConfig, ResumeSessionConfig, SectionOverride, SectionOverrideAction, SectionTransformFn, SessionCapabilities, SessionConfig, SessionEvent, SessionEventHandler, SessionEventPayload, SessionEventType, SessionLifecycleEvent, SessionLifecycleEventType, SessionLifecycleHandler, SessionContext, SessionListFilter, SessionMetadata, SessionUiApi, SessionFsConfig, SessionFsProvider, SessionFsFileInfo, SystemMessageAppendConfig, SystemMessageConfig, SystemMessageCustomizeConfig, SystemMessageReplaceConfig, SystemPromptSection, TelemetryConfig, TraceContext, TraceContextProvider, Tool, ToolHandler, ToolInvocation, ToolResultObject, TypedSessionEventHandler, TypedSessionLifecycleHandler, ZodSchema, } from "./types.js";
10
+ export type * from "./generated/session-events.js";
11
+ export type { CommandContext, CommandDefinition, CommandHandler, CloudSessionOptions, CloudSessionRepository, AutoModeSwitchHandler, AutoModeSwitchRequest, AutoModeSwitchResponse, ConnectionState, CopilotClientOptions, StdioRuntimeConnection, TcpRuntimeConnection, UriRuntimeConnection, CustomAgentConfig, ElicitationFieldValue, ElicitationHandler, ElicitationParams, ElicitationContext, ElicitationResult, ElicitationSchema, ElicitationSchemaField, ExitPlanModeHandler, ExitPlanModeRequest, ExitPlanModeResult, ForegroundSessionInfo, GetAuthStatusResponse, GetStatusResponse, InfiniteSessionConfig, UiInputOptions, MCPStdioServerConfig, MCPHTTPServerConfig, MCPServerConfig, DefaultAgentConfig, MessageOptions, ModelBilling, ModelCapabilities, ModelCapabilitiesOverride, ModelInfo, ModelPolicy, PermissionHandler, PermissionRequest, PermissionRequestResult, ProviderConfig, RemoteSessionMode, ResumeSessionConfig, SectionOverride, SectionOverrideAction, SectionTransformFn, SessionCapabilities, SessionConfig, SessionConfigBase, SessionEvent, SessionEventHandler, SessionEventPayload, SessionEventType, SessionLifecycleEvent, SessionLifecycleEventMetadata, SessionLifecycleEventType, SessionLifecycleHandler, SessionCreatedEvent, SessionDeletedEvent, SessionUpdatedEvent, SessionForegroundEvent, SessionBackgroundEvent, SessionContext, SessionListFilter, SessionMetadata, SessionUiApi, SessionFsConfig, SessionFsProvider, SessionFsFileInfo, SessionFsSqliteQueryResult, SessionFsSqliteQueryType, SessionFsSqliteProvider, SystemMessageAppendConfig, SystemMessageConfig, SystemMessageCustomizeConfig, SystemMessageReplaceConfig, SystemPromptSection, TelemetryConfig, TraceContext, TraceContextProvider, Tool, ToolHandler, ToolInvocation, ToolTelemetry, ToolResultObject, TypedSessionEventHandler, TypedSessionLifecycleHandler, ZodSchema, } from "./types.js";
package/dist/index.js CHANGED
@@ -1,4 +1,5 @@
1
1
  import { CopilotClient } from "./client.js";
2
+ import { RuntimeConnection } from "./types.js";
2
3
  import { CopilotSession } from "./session.js";
3
4
  import {
4
5
  defineTool,
@@ -10,6 +11,7 @@ import {
10
11
  export {
11
12
  CopilotClient,
12
13
  CopilotSession,
14
+ RuntimeConnection,
13
15
  SYSTEM_PROMPT_SECTIONS,
14
16
  approveAll,
15
17
  convertMcpCallToolResult,
package/dist/session.d.ts CHANGED
@@ -1,12 +1,5 @@
1
- /**
2
- * Copilot Session - represents a single conversation session with the Copilot CLI.
3
- * @module session
4
- */
5
- import type { MessageConnection } from "vscode-jsonrpc/node.js";
6
1
  import { createSessionRpc } from "./generated/rpc.js";
7
- import type { ClientSessionApiHandlers } from "./generated/rpc.js";
8
- import type { CommandHandler, AutoModeSwitchHandler, AutoModeSwitchRequest, AutoModeSwitchResponse, ElicitationHandler, ElicitationContext, ExitPlanModeHandler, ExitPlanModeRequest, ExitPlanModeResult, MessageOptions, PermissionHandler, PermissionRequestResult, ReasoningEffort, ModelCapabilitiesOverride, SectionTransformFn, SessionCapabilities, SessionEvent, SessionEventHandler, SessionEventType, SessionHooks, SessionUiApi, Tool, ToolHandler, TraceContextProvider, TypedSessionEventHandler, UserInputHandler, UserInputResponse } from "./types.js";
9
- export declare const NO_RESULT_PERMISSION_V2_ERROR = "Permission handlers cannot return 'no-result' when connected to a protocol v2 server.";
2
+ import type { MessageOptions, ReasoningEffort, ModelCapabilitiesOverride, SessionCapabilities, SessionEvent, SessionEventHandler, SessionEventType, SessionUiApi, TypedSessionEventHandler } from "./types.js";
10
3
  /** Assistant message event - the final response from the assistant. */
11
4
  export type AssistantMessageEvent = Extract<SessionEvent, {
12
5
  type: "assistant.message";
@@ -54,18 +47,6 @@ export declare class CopilotSession {
54
47
  private _rpc;
55
48
  private traceContextProvider?;
56
49
  private _capabilities;
57
- /** @internal Client session API handlers, populated by CopilotClient during create/resume. */
58
- clientSessionApis: ClientSessionApiHandlers;
59
- /**
60
- * Creates a new CopilotSession instance.
61
- *
62
- * @param sessionId - The unique identifier for this session
63
- * @param connection - The JSON-RPC message connection to the Copilot CLI
64
- * @param workspacePath - Path to the session workspace directory (when infinite sessions enabled)
65
- * @param traceContextProvider - Optional callback to get W3C Trace Context for outbound RPCs
66
- * @internal This constructor is internal. Use {@link CopilotClient.createSession} to create sessions.
67
- */
68
- constructor(sessionId: string, connection: MessageConnection, _workspacePath?: string | undefined, traceContextProvider?: TraceContextProvider);
69
50
  /**
70
51
  * Typed session-scoped RPC methods.
71
52
  */
@@ -112,6 +93,7 @@ export declare class CopilotSession {
112
93
  * });
113
94
  * ```
114
95
  */
96
+ send(prompt: string): Promise<string>;
115
97
  send(options: MessageOptions): Promise<string>;
116
98
  /**
117
99
  * Sends a message to this session and waits until the session becomes idle.
@@ -136,6 +118,7 @@ export declare class CopilotSession {
136
118
  * console.log(response?.data.content); // "4"
137
119
  * ```
138
120
  */
121
+ sendAndWait(prompt: string, timeout?: number): Promise<AssistantMessageEvent | undefined>;
139
122
  sendAndWait(options: MessageOptions, timeout?: number): Promise<AssistantMessageEvent | undefined>;
140
123
  /**
141
124
  * Subscribes to events from this session.
@@ -183,191 +166,11 @@ export declare class CopilotSession {
183
166
  * ```
184
167
  */
185
168
  on(handler: SessionEventHandler): () => void;
186
- /**
187
- * Dispatches an event to all registered handlers.
188
- * Also handles broadcast request events internally (external tool calls, permissions).
189
- *
190
- * @param event - The session event to dispatch
191
- * @internal This method is for internal use by the SDK.
192
- */
193
- _dispatchEvent(event: SessionEvent): void;
194
- /**
195
- * Handles broadcast request events by executing local handlers and responding via RPC.
196
- * Handlers are dispatched as fire-and-forget — rejections propagate as unhandled promise
197
- * rejections, consistent with standard EventEmitter / event handler semantics.
198
- * @internal
199
- */
200
- private _handleBroadcastEvent;
201
- /**
202
- * Executes a tool handler and sends the result back via RPC.
203
- * @internal
204
- */
205
- private _executeToolAndRespond;
206
- /**
207
- * Executes a permission handler and sends the result back via RPC.
208
- * @internal
209
- */
210
- private _executePermissionAndRespond;
211
- /**
212
- * Executes a command handler and sends the result back via RPC.
213
- * @internal
214
- */
215
- private _executeCommandAndRespond;
216
- /**
217
- * Registers custom tool handlers for this session.
218
- *
219
- * Tools allow the assistant to execute custom functions. When the assistant
220
- * invokes a tool, the corresponding handler is called with the tool arguments.
221
- *
222
- * @param tools - An array of tool definitions with their handlers, or undefined to clear all tools
223
- * @internal This method is typically called internally when creating a session with tools.
224
- */
225
- registerTools(tools?: Tool[]): void;
226
- /**
227
- * Retrieves a registered tool handler by name.
228
- *
229
- * @param name - The name of the tool to retrieve
230
- * @returns The tool handler if found, or undefined
231
- * @internal This method is for internal use by the SDK.
232
- */
233
- getToolHandler(name: string): ToolHandler | undefined;
234
- /**
235
- * Registers command handlers for this session.
236
- *
237
- * @param commands - An array of command definitions with handlers, or undefined to clear
238
- * @internal This method is typically called internally when creating/resuming a session.
239
- */
240
- registerCommands(commands?: {
241
- name: string;
242
- handler: CommandHandler;
243
- }[]): void;
244
- /**
245
- * Registers the elicitation handler for this session.
246
- *
247
- * @param handler - The handler to invoke when the server dispatches an elicitation request
248
- * @internal This method is typically called internally when creating/resuming a session.
249
- */
250
- registerElicitationHandler(handler?: ElicitationHandler): void;
251
- /**
252
- * Registers the exit-plan-mode handler for this session.
253
- *
254
- * @param handler - The handler to invoke when the server dispatches an exit-plan-mode request
255
- * @internal This method is typically called internally when creating/resuming a session.
256
- */
257
- registerExitPlanModeHandler(handler?: ExitPlanModeHandler): void;
258
- /**
259
- * Registers the auto-mode-switch handler for this session.
260
- *
261
- * @param handler - The handler to invoke when the server dispatches an auto-mode-switch request
262
- * @internal This method is typically called internally when creating/resuming a session.
263
- */
264
- registerAutoModeSwitchHandler(handler?: AutoModeSwitchHandler): void;
265
- /**
266
- * Handles an elicitation.requested broadcast event.
267
- * Invokes the registered handler and responds via handlePendingElicitation RPC.
268
- * @internal
269
- */
270
- _handleElicitationRequest(context: ElicitationContext, requestId: string): Promise<void>;
271
- /**
272
- * Handles an exitPlanMode.request callback from the runtime.
273
- * @internal
274
- */
275
- _handleExitPlanModeRequest(request: ExitPlanModeRequest): Promise<ExitPlanModeResult>;
276
- /**
277
- * Handles an autoModeSwitch.request callback from the runtime.
278
- * @internal
279
- */
280
- _handleAutoModeSwitchRequest(request: AutoModeSwitchRequest): Promise<AutoModeSwitchResponse>;
281
- /**
282
- * Sets the host capabilities for this session.
283
- *
284
- * @param capabilities - The capabilities object from the create/resume response
285
- * @internal This method is typically called internally when creating/resuming a session.
286
- */
287
- setCapabilities(capabilities?: SessionCapabilities): void;
288
169
  private assertElicitation;
289
170
  private _elicitation;
290
171
  private _confirm;
291
172
  private _select;
292
173
  private _input;
293
- /**
294
- * Registers a handler for permission requests.
295
- *
296
- * When the assistant needs permission to perform certain actions (e.g., file operations),
297
- * this handler is called to approve or deny the request.
298
- *
299
- * @param handler - The permission handler function, or undefined to remove the handler
300
- * @internal This method is typically called internally when creating a session.
301
- */
302
- registerPermissionHandler(handler?: PermissionHandler): void;
303
- /**
304
- * Registers a user input handler for ask_user requests.
305
- *
306
- * When the agent needs input from the user (via ask_user tool),
307
- * this handler is called to provide the response.
308
- *
309
- * @param handler - The user input handler function, or undefined to remove the handler
310
- * @internal This method is typically called internally when creating a session.
311
- */
312
- registerUserInputHandler(handler?: UserInputHandler): void;
313
- /**
314
- * Registers hook handlers for session lifecycle events.
315
- *
316
- * Hooks allow custom logic to be executed at various points during
317
- * the session lifecycle (before/after tool use, session start/end, etc.).
318
- *
319
- * @param hooks - The hook handlers object, or undefined to remove all hooks
320
- * @internal This method is typically called internally when creating a session.
321
- */
322
- registerHooks(hooks?: SessionHooks): void;
323
- /**
324
- * Registers transform callbacks for system message sections.
325
- *
326
- * @param callbacks - Map of section ID to transform callback, or undefined to clear
327
- * @internal This method is typically called internally when creating a session.
328
- */
329
- registerTransformCallbacks(callbacks?: Map<string, SectionTransformFn>): void;
330
- /**
331
- * Handles a systemMessage.transform request from the runtime.
332
- * Dispatches each section to its registered transform callback.
333
- *
334
- * @param sections - Map of section IDs to their current rendered content
335
- * @returns A promise that resolves with the transformed sections
336
- * @internal This method is for internal use by the SDK.
337
- */
338
- _handleSystemMessageTransform(sections: Record<string, {
339
- content: string;
340
- }>): Promise<{
341
- sections: Record<string, {
342
- content: string;
343
- }>;
344
- }>;
345
- /**
346
- * Handles a permission request in the v2 protocol format (synchronous RPC).
347
- * Used as a back-compat adapter when connected to a v2 server.
348
- *
349
- * @param request - The permission request data from the CLI
350
- * @returns A promise that resolves with the permission decision
351
- * @internal This method is for internal use by the SDK.
352
- */
353
- _handlePermissionRequestV2(request: unknown): Promise<PermissionRequestResult>;
354
- /**
355
- * Handles a user input request from the Copilot CLI.
356
- *
357
- * @param request - The user input request data from the CLI
358
- * @returns A promise that resolves with the user's response
359
- * @internal This method is for internal use by the SDK.
360
- */
361
- _handleUserInputRequest(request: unknown): Promise<UserInputResponse>;
362
- /**
363
- * Handles a hooks invocation from the Copilot CLI.
364
- *
365
- * @param hookType - The type of hook being invoked
366
- * @param input - The input data for the hook
367
- * @returns A promise that resolves with the hook output, or undefined
368
- * @internal This method is for internal use by the SDK.
369
- */
370
- _handleHooksInvoke(hookType: string, input: unknown): Promise<unknown>;
371
174
  /**
372
175
  * Retrieves all events and messages from this session's history.
373
176
  *
@@ -379,7 +182,7 @@ export declare class CopilotSession {
379
182
  *
380
183
  * @example
381
184
  * ```typescript
382
- * const events = await session.getMessages();
185
+ * const events = await session.getEvents();
383
186
  * for (const event of events) {
384
187
  * if (event.type === "assistant.message") {
385
188
  * console.log("Assistant:", event.data.content);
@@ -387,7 +190,7 @@ export declare class CopilotSession {
387
190
  * }
388
191
  * ```
389
192
  */
390
- getMessages(): Promise<SessionEvent[]>;
193
+ getEvents(): Promise<SessionEvent[]>;
391
194
  /**
392
195
  * Disconnects this session and releases all in-memory resources (event handlers,
393
196
  * tool handlers, permission handlers).
@@ -410,16 +213,6 @@ export declare class CopilotSession {
410
213
  * ```
411
214
  */
412
215
  disconnect(): Promise<void>;
413
- /**
414
- * @deprecated Use {@link disconnect} instead. This method will be removed in a future release.
415
- *
416
- * Disconnects this session and releases all in-memory resources.
417
- * Session data on disk is preserved for later resumption.
418
- *
419
- * @returns A promise that resolves when the session is disconnected
420
- * @throws Error if the connection fails
421
- */
422
- destroy(): Promise<void>;
423
216
  /** Enables `await using session = ...` syntax for automatic cleanup. */
424
217
  [Symbol.asyncDispose](): Promise<void>;
425
218
  /**
package/dist/session.js CHANGED
@@ -2,6 +2,14 @@ import { ConnectionError, ResponseError } from "vscode-jsonrpc/node.js";
2
2
  import { createSessionRpc } from "./generated/rpc.js";
3
3
  import { getTraceContext } from "./telemetry.js";
4
4
  const NO_RESULT_PERMISSION_V2_ERROR = "Permission handlers cannot return 'no-result' when connected to a protocol v2 server.";
5
+ function deserializeHookInput(raw) {
6
+ if (!raw || typeof raw !== "object" || typeof raw.timestamp !== "number") {
7
+ return raw;
8
+ }
9
+ const obj = raw;
10
+ const { cwd, ...rest } = obj;
11
+ return { ...rest, timestamp: new Date(obj.timestamp), workingDirectory: cwd };
12
+ }
5
13
  class CopilotSession {
6
14
  /**
7
15
  * Creates a new CopilotSession instance.
@@ -78,25 +86,8 @@ class CopilotSession {
78
86
  input: (message, options) => this._input(message, options)
79
87
  };
80
88
  }
81
- /**
82
- * Sends a message to this session and waits for the response.
83
- *
84
- * The message is processed asynchronously. Subscribe to events via {@link on}
85
- * to receive streaming responses and other session events.
86
- *
87
- * @param options - The message options including the prompt and optional attachments
88
- * @returns A promise that resolves with the message ID of the response
89
- * @throws Error if the session has been disconnected or the connection fails
90
- *
91
- * @example
92
- * ```typescript
93
- * const messageId = await session.send({
94
- * prompt: "Explain this code",
95
- * attachments: [{ type: "file", path: "./src/index.ts" }]
96
- * });
97
- * ```
98
- */
99
- async send(options) {
89
+ async send(optionsOrPrompt) {
90
+ const options = typeof optionsOrPrompt === "string" ? { prompt: optionsOrPrompt } : optionsOrPrompt;
100
91
  const response = await this.connection.sendRequest("session.send", {
101
92
  ...await getTraceContext(this.traceContextProvider),
102
93
  sessionId: this.sessionId,
@@ -107,30 +98,8 @@ class CopilotSession {
107
98
  });
108
99
  return response.messageId;
109
100
  }
110
- /**
111
- * Sends a message to this session and waits until the session becomes idle.
112
- *
113
- * This is a convenience method that combines {@link send} with waiting for
114
- * the `session.idle` event. Use this when you want to block until the
115
- * assistant has finished processing the message.
116
- *
117
- * Events are still delivered to handlers registered via {@link on} while waiting.
118
- *
119
- * @param options - The message options including the prompt and optional attachments
120
- * @param timeout - Timeout in milliseconds (default: 60000). Controls how long to wait; does not abort in-flight agent work.
121
- * @returns A promise that resolves with the final assistant message when the session becomes idle,
122
- * or undefined if no assistant message was received
123
- * @throws Error if the timeout is reached before the session becomes idle
124
- * @throws Error if the session has been disconnected or the connection fails
125
- *
126
- * @example
127
- * ```typescript
128
- * // Send and wait for completion with default 60s timeout
129
- * const response = await session.sendAndWait({ prompt: "What is 2+2?" });
130
- * console.log(response?.data.content); // "4"
131
- * ```
132
- */
133
- async sendAndWait(options, timeout) {
101
+ async sendAndWait(optionsOrPrompt, timeout) {
102
+ const options = typeof optionsOrPrompt === "string" ? { prompt: optionsOrPrompt } : optionsOrPrompt;
134
103
  const effectiveTimeout = timeout ?? 6e4;
135
104
  let resolveIdle;
136
105
  let rejectWithError;
@@ -373,8 +342,8 @@ class CopilotSession {
373
342
  /**
374
343
  * Registers custom tool handlers for this session.
375
344
  *
376
- * Tools allow the assistant to execute custom functions. When the assistant
377
- * invokes a tool, the corresponding handler is called with the tool arguments.
345
+ * Tools with handlers allow the assistant to execute custom functions automatically.
346
+ * Declaration-only tools are surfaced as events and left pending for the consumer.
378
347
  *
379
348
  * @param tools - An array of tool definitions with their handlers, or undefined to clear all tools
380
349
  * @internal This method is typically called internally when creating a session with tools.
@@ -385,7 +354,9 @@ class CopilotSession {
385
354
  return;
386
355
  }
387
356
  for (const tool of tools) {
388
- this.toolHandlers.set(tool.name, tool.handler);
357
+ if (tool.handler) {
358
+ this.toolHandlers.set(tool.name, tool.handler);
359
+ }
389
360
  }
390
361
  }
391
362
  /**
@@ -692,8 +663,10 @@ class CopilotSession {
692
663
  if (!this.hooks) {
693
664
  return void 0;
694
665
  }
666
+ const normalized = deserializeHookInput(input);
695
667
  const handlerMap = {
696
668
  preToolUse: this.hooks.onPreToolUse,
669
+ preMcpToolCall: this.hooks.onPreMcpToolCall,
697
670
  postToolUse: this.hooks.onPostToolUse,
698
671
  userPromptSubmitted: this.hooks.onUserPromptSubmitted,
699
672
  sessionStart: this.hooks.onSessionStart,
@@ -705,7 +678,7 @@ class CopilotSession {
705
678
  return void 0;
706
679
  }
707
680
  try {
708
- const result = await handler(input, { sessionId: this.sessionId });
681
+ const result = await handler(normalized, { sessionId: this.sessionId });
709
682
  return result;
710
683
  } catch (_error) {
711
684
  return void 0;
@@ -722,7 +695,7 @@ class CopilotSession {
722
695
  *
723
696
  * @example
724
697
  * ```typescript
725
- * const events = await session.getMessages();
698
+ * const events = await session.getEvents();
726
699
  * for (const event of events) {
727
700
  * if (event.type === "assistant.message") {
728
701
  * console.log("Assistant:", event.data.content);
@@ -730,7 +703,7 @@ class CopilotSession {
730
703
  * }
731
704
  * ```
732
705
  */
733
- async getMessages() {
706
+ async getEvents() {
734
707
  const response = await this.connection.sendRequest("session.getMessages", {
735
708
  sessionId: this.sessionId
736
709
  });
@@ -770,18 +743,6 @@ class CopilotSession {
770
743
  this.exitPlanModeHandler = void 0;
771
744
  this.autoModeSwitchHandler = void 0;
772
745
  }
773
- /**
774
- * @deprecated Use {@link disconnect} instead. This method will be removed in a future release.
775
- *
776
- * Disconnects this session and releases all in-memory resources.
777
- * Session data on disk is preserved for later resumption.
778
- *
779
- * @returns A promise that resolves when the session is disconnected
780
- * @throws Error if the connection fails
781
- */
782
- async destroy() {
783
- return this.disconnect();
784
- }
785
746
  /** Enables `await using session = ...` syntax for automatic cleanup. */
786
747
  async [Symbol.asyncDispose]() {
787
748
  return this.disconnect();
@@ -1,10 +1,35 @@
1
- import type { SessionFsHandler, SessionFsStatResult, SessionFsReaddirWithTypesEntry } from "./generated/rpc.js";
1
+ import type { SessionFsHandler, SessionFsStatResult, SessionFsReaddirWithTypesEntry, SessionFsSqliteQueryResult as GeneratedSqliteQueryResult, SessionFsSqliteQueryType } from "./generated/rpc.js";
2
+ export type { SessionFsSqliteQueryType };
2
3
  /**
3
4
  * File metadata returned by {@link SessionFsProvider.stat}.
4
5
  * Same shape as the generated {@link SessionFsStatResult} but without the
5
6
  * `error` field, since providers signal errors by throwing.
6
7
  */
7
8
  export type SessionFsFileInfo = Omit<SessionFsStatResult, "error">;
9
+ /**
10
+ * Result of a SQLite query execution via {@link SessionFsSqliteProvider.query}.
11
+ * Same shape as the generated {@link GeneratedSqliteQueryResult} but without the
12
+ * `error` field, since providers signal errors by throwing.
13
+ */
14
+ export type SessionFsSqliteQueryResult = Omit<GeneratedSqliteQueryResult, "error">;
15
+ /**
16
+ * SQLite operations for the per-session database.
17
+ * Implementers provide query execution and existence checking.
18
+ */
19
+ export interface SessionFsSqliteProvider {
20
+ /**
21
+ * Execute a SQLite query against the per-session database.
22
+ *
23
+ * @param queryType - How to execute: `"exec"` for DDL/multi-statement, `"query"` for SELECT, `"run"` for INSERT/UPDATE/DELETE.
24
+ * @param query - SQL query to execute.
25
+ * @param params - Optional named bind parameters.
26
+ */
27
+ query(queryType: SessionFsSqliteQueryType, query: string, params?: Record<string, string | number | null>): Promise<SessionFsSqliteQueryResult | undefined>;
28
+ /**
29
+ * Check whether the per-session database already exists, without creating it.
30
+ */
31
+ exists(): Promise<boolean>;
32
+ }
8
33
  /**
9
34
  * Interface for session filesystem providers. Implementers use idiomatic
10
35
  * TypeScript patterns: throw on error, return values directly. Use
@@ -35,6 +60,8 @@ export interface SessionFsProvider {
35
60
  rm(path: string, recursive: boolean, force: boolean): Promise<void>;
36
61
  /** Renames/moves a file or directory. */
37
62
  rename(src: string, dest: string): Promise<void>;
63
+ /** Per-session SQLite database operations. Optional — omit if the provider does not support SQLite. */
64
+ sqlite?: SessionFsSqliteProvider;
38
65
  }
39
66
  /**
40
67
  * Wraps a {@link SessionFsProvider} into the {@link SessionFsHandler}
@@ -1,3 +1,15 @@
1
+ function normalizeSqliteParams(params) {
2
+ if (!params) {
3
+ return void 0;
4
+ }
5
+ const normalized = {};
6
+ for (const [key, value] of Object.entries(params)) {
7
+ if (value !== void 0) {
8
+ normalized[key] = value;
9
+ }
10
+ }
11
+ return normalized;
12
+ }
1
13
  function createSessionFsAdapter(provider) {
2
14
  return {
3
15
  readFile: async ({ path }) => {
@@ -84,6 +96,28 @@ function createSessionFsAdapter(provider) {
84
96
  } catch (err) {
85
97
  return toSessionFsError(err);
86
98
  }
99
+ },
100
+ // Unlike the FS methods above, SQLite methods let errors propagate to the JSON-RPC layer
101
+ // rather than catching and mapping via toSessionFsError. The FS error mapping is specifically
102
+ // for translating Node.js errno codes (e.g., ENOENT) into SessionFsError, which isn't
103
+ // meaningful for SQL errors. Letting exceptions propagate preserves the original error
104
+ // message in the JSON-RPC error response.
105
+ sqliteQuery: async ({ queryType, query, params: bindParams }) => {
106
+ if (!provider.sqlite) {
107
+ throw new Error("SQLite is not supported by this provider");
108
+ }
109
+ const result = await provider.sqlite.query(
110
+ queryType,
111
+ query,
112
+ normalizeSqliteParams(bindParams)
113
+ );
114
+ return result ?? { rows: [], columns: [], rowsAffected: 0 };
115
+ },
116
+ sqliteExists: async () => {
117
+ if (!provider.sqlite) {
118
+ throw new Error("SQLite is not supported by this provider");
119
+ }
120
+ return { exists: await provider.sqlite.exists() };
87
121
  }
88
122
  };
89
123
  }