@github/copilot-sdk 0.1.24-preview.0 → 0.1.25-preview.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -10,6 +10,19 @@ TypeScript SDK for programmatic control of GitHub Copilot CLI via JSON-RPC.
10
10
  npm install @github/copilot-sdk
11
11
  ```
12
12
 
13
+ ## Run the Sample
14
+
15
+ Try the interactive chat sample (from the repo root):
16
+
17
+ ```bash
18
+ cd nodejs
19
+ npm ci
20
+ npm run build
21
+ cd samples
22
+ npm install
23
+ npm start
24
+ ```
25
+
13
26
  ## Quick Start
14
27
 
15
28
  ```typescript
@@ -108,9 +121,25 @@ Ping the server to check connectivity.
108
121
 
109
122
  Get current connection state.
110
123
 
111
- ##### `listSessions(): Promise<SessionMetadata[]>`
124
+ ##### `listSessions(filter?: SessionListFilter): Promise<SessionMetadata[]>`
125
+
126
+ List all available sessions. Optionally filter by working directory context.
127
+
128
+ **SessionMetadata:**
129
+
130
+ - `sessionId: string` - Unique session identifier
131
+ - `startTime: Date` - When the session was created
132
+ - `modifiedTime: Date` - When the session was last modified
133
+ - `summary?: string` - Optional session summary
134
+ - `isRemote: boolean` - Whether the session is remote
135
+ - `context?: SessionContext` - Working directory context from session creation
136
+
137
+ **SessionContext:**
112
138
 
113
- List all available sessions.
139
+ - `cwd: string` - Working directory where the session was created
140
+ - `gitRoot?: string` - Git repository root (if in a git repo)
141
+ - `repository?: string` - GitHub repository in "owner/repo" format
142
+ - `branch?: string` - Current git branch
114
143
 
115
144
  ##### `deleteSession(sessionId: string): Promise<void>`
116
145
 
package/dist/client.d.ts CHANGED
@@ -1,5 +1,6 @@
1
+ import { createServerRpc } from "./generated/rpc.js";
1
2
  import { CopilotSession } from "./session.js";
2
- import type { ConnectionState, CopilotClientOptions, GetAuthStatusResponse, GetStatusResponse, ModelInfo, ResumeSessionConfig, SessionConfig, SessionLifecycleEventType, SessionLifecycleHandler, SessionMetadata, TypedSessionLifecycleHandler } from "./types.js";
3
+ import type { ConnectionState, CopilotClientOptions, GetAuthStatusResponse, GetStatusResponse, ModelInfo, ResumeSessionConfig, SessionConfig, SessionLifecycleEventType, SessionLifecycleHandler, SessionListFilter, SessionMetadata, TypedSessionLifecycleHandler } from "./types.js";
3
4
  export declare class CopilotClient {
4
5
  private cliProcess;
5
6
  private connection;
@@ -8,6 +9,7 @@ export declare class CopilotClient {
8
9
  private actualHost;
9
10
  private state;
10
11
  private sessions;
12
+ private stderrBuffer;
11
13
  private options;
12
14
  private isExternalServer;
13
15
  private forceStopping;
@@ -15,6 +17,13 @@ export declare class CopilotClient {
15
17
  private modelsCacheLock;
16
18
  private sessionLifecycleHandlers;
17
19
  private typedLifecycleHandlers;
20
+ private _rpc;
21
+ private processExitPromise;
22
+ /**
23
+ * Typed server-scoped RPC methods.
24
+ * @throws Error if the client is not connected
25
+ */
26
+ get rpc(): ReturnType<typeof createServerRpc>;
18
27
  /**
19
28
  * Creates a new CopilotClient instance.
20
29
  *
@@ -247,22 +256,19 @@ export declare class CopilotClient {
247
256
  */
248
257
  deleteSession(sessionId: string): Promise<void>;
249
258
  /**
250
- * Lists all available sessions known to the server.
259
+ * List all available sessions.
251
260
  *
252
- * Returns metadata about each session including ID, timestamps, and summary.
253
- *
254
- * @returns A promise that resolves with an array of session metadata
255
- * @throws Error if the client is not connected
261
+ * @param filter - Optional filter to limit returned sessions by context fields
256
262
  *
257
263
  * @example
258
- * ```typescript
264
+ * // List all sessions
259
265
  * const sessions = await client.listSessions();
260
- * for (const session of sessions) {
261
- * console.log(`${session.sessionId}: ${session.summary}`);
262
- * }
263
- * ```
266
+ *
267
+ * @example
268
+ * // List sessions for a specific repository
269
+ * const sessions = await client.listSessions({ repository: "owner/repo" });
264
270
  */
265
- listSessions(): Promise<SessionMetadata[]>;
271
+ listSessions(filter?: SessionListFilter): Promise<SessionMetadata[]>;
266
272
  /**
267
273
  * Gets the foreground session ID in TUI+server mode.
268
274
  *
package/dist/client.js CHANGED
@@ -8,6 +8,7 @@ import {
8
8
  StreamMessageReader,
9
9
  StreamMessageWriter
10
10
  } from "vscode-jsonrpc/node.js";
11
+ import { createServerRpc } from "./generated/rpc.js";
11
12
  import { getSdkProtocolVersion } from "./sdkProtocolVersion.js";
12
13
  import { CopilotSession } from "./session.js";
13
14
  function isZodSchema(value) {
@@ -33,6 +34,8 @@ class CopilotClient {
33
34
  actualHost = "localhost";
34
35
  state = "disconnected";
35
36
  sessions = /* @__PURE__ */ new Map();
37
+ stderrBuffer = "";
38
+ // Captures CLI stderr for error messages
36
39
  options;
37
40
  isExternalServer = false;
38
41
  forceStopping = false;
@@ -40,6 +43,22 @@ class CopilotClient {
40
43
  modelsCacheLock = Promise.resolve();
41
44
  sessionLifecycleHandlers = /* @__PURE__ */ new Set();
42
45
  typedLifecycleHandlers = /* @__PURE__ */ new Map();
46
+ _rpc = null;
47
+ processExitPromise = null;
48
+ // Rejects when CLI process exits
49
+ /**
50
+ * Typed server-scoped RPC methods.
51
+ * @throws Error if the client is not connected
52
+ */
53
+ get rpc() {
54
+ if (!this.connection) {
55
+ throw new Error("Client is not connected. Call start() first.");
56
+ }
57
+ if (!this._rpc) {
58
+ this._rpc = createServerRpc(this.connection);
59
+ }
60
+ return this._rpc;
61
+ }
43
62
  /**
44
63
  * Creates a new CopilotClient instance.
45
64
  *
@@ -207,6 +226,7 @@ class CopilotClient {
207
226
  );
208
227
  }
209
228
  this.connection = null;
229
+ this._rpc = null;
210
230
  }
211
231
  this.modelsCache = null;
212
232
  if (this.socket) {
@@ -235,6 +255,8 @@ class CopilotClient {
235
255
  }
236
256
  this.state = "disconnected";
237
257
  this.actualPort = null;
258
+ this.stderrBuffer = "";
259
+ this.processExitPromise = null;
238
260
  return errors;
239
261
  }
240
262
  /**
@@ -271,6 +293,7 @@ class CopilotClient {
271
293
  } catch {
272
294
  }
273
295
  this.connection = null;
296
+ this._rpc = null;
274
297
  }
275
298
  this.modelsCache = null;
276
299
  if (this.socket) {
@@ -289,6 +312,8 @@ class CopilotClient {
289
312
  }
290
313
  this.state = "disconnected";
291
314
  this.actualPort = null;
315
+ this.stderrBuffer = "";
316
+ this.processExitPromise = null;
292
317
  }
293
318
  /**
294
319
  * Creates a new conversation session with the Copilot CLI.
@@ -345,6 +370,7 @@ class CopilotClient {
345
370
  workingDirectory: config.workingDirectory,
346
371
  streaming: config.streaming,
347
372
  mcpServers: config.mcpServers,
373
+ envValueMode: "direct",
348
374
  customAgents: config.customAgents,
349
375
  configDir: config.configDir,
350
376
  skillDirectories: config.skillDirectories,
@@ -417,6 +443,7 @@ class CopilotClient {
417
443
  configDir: config.configDir,
418
444
  streaming: config.streaming,
419
445
  mcpServers: config.mcpServers,
446
+ envValueMode: "direct",
420
447
  customAgents: config.customAgents,
421
448
  skillDirectories: config.skillDirectories,
422
449
  disabledSkills: config.disabledSkills,
@@ -528,7 +555,12 @@ class CopilotClient {
528
555
  */
529
556
  async verifyProtocolVersion() {
530
557
  const expectedVersion = getSdkProtocolVersion();
531
- const pingResult = await this.ping();
558
+ let pingResult;
559
+ if (this.processExitPromise) {
560
+ pingResult = await Promise.race([this.ping(), this.processExitPromise]);
561
+ } else {
562
+ pingResult = await this.ping();
563
+ }
532
564
  const serverVersion = pingResult.protocolVersion;
533
565
  if (serverVersion === void 0) {
534
566
  throw new Error(
@@ -594,33 +626,31 @@ class CopilotClient {
594
626
  this.sessions.delete(sessionId);
595
627
  }
596
628
  /**
597
- * Lists all available sessions known to the server.
629
+ * List all available sessions.
598
630
  *
599
- * Returns metadata about each session including ID, timestamps, and summary.
600
- *
601
- * @returns A promise that resolves with an array of session metadata
602
- * @throws Error if the client is not connected
631
+ * @param filter - Optional filter to limit returned sessions by context fields
603
632
  *
604
633
  * @example
605
- * ```typescript
634
+ * // List all sessions
606
635
  * const sessions = await client.listSessions();
607
- * for (const session of sessions) {
608
- * console.log(`${session.sessionId}: ${session.summary}`);
609
- * }
610
- * ```
636
+ *
637
+ * @example
638
+ * // List sessions for a specific repository
639
+ * const sessions = await client.listSessions({ repository: "owner/repo" });
611
640
  */
612
- async listSessions() {
641
+ async listSessions(filter) {
613
642
  if (!this.connection) {
614
643
  throw new Error("Client not connected");
615
644
  }
616
- const response = await this.connection.sendRequest("session.list", {});
645
+ const response = await this.connection.sendRequest("session.list", { filter });
617
646
  const { sessions } = response;
618
647
  return sessions.map((s) => ({
619
648
  sessionId: s.sessionId,
620
649
  startTime: new Date(s.startTime),
621
650
  modifiedTime: new Date(s.modifiedTime),
622
651
  summary: s.summary,
623
- isRemote: s.isRemote
652
+ isRemote: s.isRemote,
653
+ context: s.context
624
654
  }));
625
655
  }
626
656
  /**
@@ -699,6 +729,7 @@ class CopilotClient {
699
729
  */
700
730
  async startCLIServer() {
701
731
  return new Promise((resolve, reject) => {
732
+ this.stderrBuffer = "";
702
733
  const args = [
703
734
  ...this.options.cliArgs,
704
735
  "--headless",
@@ -733,13 +764,15 @@ class CopilotClient {
733
764
  this.cliProcess = spawn(process.execPath, [this.options.cliPath, ...args], {
734
765
  stdio: stdioConfig,
735
766
  cwd: this.options.cwd,
736
- env: envWithoutNodeDebug
767
+ env: envWithoutNodeDebug,
768
+ windowsHide: true
737
769
  });
738
770
  } else {
739
771
  this.cliProcess = spawn(this.options.cliPath, args, {
740
772
  stdio: stdioConfig,
741
773
  cwd: this.options.cwd,
742
- env: envWithoutNodeDebug
774
+ env: envWithoutNodeDebug,
775
+ windowsHide: true
743
776
  });
744
777
  }
745
778
  let stdout = "";
@@ -759,6 +792,7 @@ class CopilotClient {
759
792
  });
760
793
  }
761
794
  this.cliProcess.stderr?.on("data", (data) => {
795
+ this.stderrBuffer += data.toString();
762
796
  const lines = data.toString().split("\n");
763
797
  for (const line of lines) {
764
798
  if (line.trim()) {
@@ -770,13 +804,54 @@ class CopilotClient {
770
804
  this.cliProcess.on("error", (error) => {
771
805
  if (!resolved) {
772
806
  resolved = true;
773
- reject(new Error(`Failed to start CLI server: ${error.message}`));
807
+ const stderrOutput = this.stderrBuffer.trim();
808
+ if (stderrOutput) {
809
+ reject(
810
+ new Error(
811
+ `Failed to start CLI server: ${error.message}
812
+ stderr: ${stderrOutput}`
813
+ )
814
+ );
815
+ } else {
816
+ reject(new Error(`Failed to start CLI server: ${error.message}`));
817
+ }
774
818
  }
775
819
  });
820
+ this.processExitPromise = new Promise((_, rejectProcessExit) => {
821
+ this.cliProcess.on("exit", (code) => {
822
+ setTimeout(() => {
823
+ const stderrOutput = this.stderrBuffer.trim();
824
+ if (stderrOutput) {
825
+ rejectProcessExit(
826
+ new Error(
827
+ `CLI server exited with code ${code}
828
+ stderr: ${stderrOutput}`
829
+ )
830
+ );
831
+ } else {
832
+ rejectProcessExit(
833
+ new Error(`CLI server exited unexpectedly with code ${code}`)
834
+ );
835
+ }
836
+ }, 50);
837
+ });
838
+ });
839
+ this.processExitPromise.catch(() => {
840
+ });
776
841
  this.cliProcess.on("exit", (code) => {
777
842
  if (!resolved) {
778
843
  resolved = true;
779
- reject(new Error(`CLI server exited with code ${code}`));
844
+ const stderrOutput = this.stderrBuffer.trim();
845
+ if (stderrOutput) {
846
+ reject(
847
+ new Error(
848
+ `CLI server exited with code ${code}
849
+ stderr: ${stderrOutput}`
850
+ )
851
+ );
852
+ } else {
853
+ reject(new Error(`CLI server exited with code ${code}`));
854
+ }
780
855
  } else if (this.options.autoRestart && this.state === "connected") {
781
856
  void this.reconnect();
782
857
  }
@@ -0,0 +1,326 @@
1
+ /**
2
+ * AUTO-GENERATED FILE - DO NOT EDIT
3
+ * Generated from: api.schema.json
4
+ */
5
+ import type { MessageConnection } from "vscode-jsonrpc/node.js";
6
+ export interface PingResult {
7
+ /**
8
+ * Echoed message (or default greeting)
9
+ */
10
+ message: string;
11
+ /**
12
+ * Server timestamp in milliseconds
13
+ */
14
+ timestamp: number;
15
+ /**
16
+ * Server protocol version number
17
+ */
18
+ protocolVersion: number;
19
+ }
20
+ export interface PingParams {
21
+ /**
22
+ * Optional message to echo back
23
+ */
24
+ message?: string;
25
+ }
26
+ export interface ModelsListResult {
27
+ /**
28
+ * List of available models with full metadata
29
+ */
30
+ models: {
31
+ /**
32
+ * Model identifier (e.g., "claude-sonnet-4.5")
33
+ */
34
+ id: string;
35
+ /**
36
+ * Display name
37
+ */
38
+ name: string;
39
+ /**
40
+ * Model capabilities and limits
41
+ */
42
+ capabilities: {
43
+ supports: {
44
+ vision: boolean;
45
+ /**
46
+ * Whether this model supports reasoning effort configuration
47
+ */
48
+ reasoningEffort: boolean;
49
+ };
50
+ limits: {
51
+ max_prompt_tokens?: number;
52
+ max_output_tokens?: number;
53
+ max_context_window_tokens: number;
54
+ };
55
+ };
56
+ /**
57
+ * Policy state (if applicable)
58
+ */
59
+ policy?: {
60
+ state: string;
61
+ terms: string;
62
+ };
63
+ /**
64
+ * Billing information
65
+ */
66
+ billing?: {
67
+ multiplier: number;
68
+ };
69
+ /**
70
+ * Supported reasoning effort levels (only present if model supports reasoning effort)
71
+ */
72
+ supportedReasoningEfforts?: string[];
73
+ /**
74
+ * Default reasoning effort level (only present if model supports reasoning effort)
75
+ */
76
+ defaultReasoningEffort?: string;
77
+ }[];
78
+ }
79
+ export interface ToolsListResult {
80
+ /**
81
+ * List of available built-in tools with metadata
82
+ */
83
+ tools: {
84
+ /**
85
+ * Tool identifier (e.g., "bash", "grep", "str_replace_editor")
86
+ */
87
+ name: string;
88
+ /**
89
+ * Optional namespaced name for declarative filtering (e.g., "playwright/navigate" for MCP tools)
90
+ */
91
+ namespacedName?: string;
92
+ /**
93
+ * Description of what the tool does
94
+ */
95
+ description: string;
96
+ /**
97
+ * JSON Schema for the tool's input parameters
98
+ */
99
+ parameters?: {
100
+ [k: string]: unknown;
101
+ };
102
+ /**
103
+ * Optional instructions for how to use this tool effectively
104
+ */
105
+ instructions?: string;
106
+ }[];
107
+ }
108
+ export interface ToolsListParams {
109
+ /**
110
+ * Optional model ID — when provided, the returned tool list reflects model-specific overrides
111
+ */
112
+ model?: string;
113
+ }
114
+ export interface AccountGetQuotaResult {
115
+ /**
116
+ * Quota snapshots keyed by type (e.g., chat, completions, premium_interactions)
117
+ */
118
+ quotaSnapshots: {
119
+ [k: string]: {
120
+ /**
121
+ * Number of requests included in the entitlement
122
+ */
123
+ entitlementRequests: number;
124
+ /**
125
+ * Number of requests used so far this period
126
+ */
127
+ usedRequests: number;
128
+ /**
129
+ * Percentage of entitlement remaining
130
+ */
131
+ remainingPercentage: number;
132
+ /**
133
+ * Number of overage requests made this period
134
+ */
135
+ overage: number;
136
+ /**
137
+ * Whether pay-per-request usage is allowed when quota is exhausted
138
+ */
139
+ overageAllowedWithExhaustedQuota: boolean;
140
+ /**
141
+ * Date when the quota resets (ISO 8601)
142
+ */
143
+ resetDate?: string;
144
+ };
145
+ };
146
+ }
147
+ export interface SessionModelGetCurrentResult {
148
+ modelId?: string;
149
+ }
150
+ export interface SessionModelGetCurrentParams {
151
+ /**
152
+ * Target session identifier
153
+ */
154
+ sessionId: string;
155
+ }
156
+ export interface SessionModelSwitchToResult {
157
+ modelId?: string;
158
+ }
159
+ export interface SessionModelSwitchToParams {
160
+ /**
161
+ * Target session identifier
162
+ */
163
+ sessionId: string;
164
+ modelId: string;
165
+ }
166
+ export interface SessionModeGetResult {
167
+ /**
168
+ * The current agent mode.
169
+ */
170
+ mode: "interactive" | "plan" | "autopilot";
171
+ }
172
+ export interface SessionModeGetParams {
173
+ /**
174
+ * Target session identifier
175
+ */
176
+ sessionId: string;
177
+ }
178
+ export interface SessionModeSetResult {
179
+ /**
180
+ * The agent mode after switching.
181
+ */
182
+ mode: "interactive" | "plan" | "autopilot";
183
+ }
184
+ export interface SessionModeSetParams {
185
+ /**
186
+ * Target session identifier
187
+ */
188
+ sessionId: string;
189
+ /**
190
+ * The mode to switch to. Valid values: "interactive", "plan", "autopilot".
191
+ */
192
+ mode: "interactive" | "plan" | "autopilot";
193
+ }
194
+ export interface SessionPlanReadResult {
195
+ /**
196
+ * Whether plan.md exists in the workspace
197
+ */
198
+ exists: boolean;
199
+ /**
200
+ * The content of plan.md, or null if it does not exist
201
+ */
202
+ content: string | null;
203
+ }
204
+ export interface SessionPlanReadParams {
205
+ /**
206
+ * Target session identifier
207
+ */
208
+ sessionId: string;
209
+ }
210
+ export interface SessionPlanUpdateResult {
211
+ }
212
+ export interface SessionPlanUpdateParams {
213
+ /**
214
+ * Target session identifier
215
+ */
216
+ sessionId: string;
217
+ /**
218
+ * The new content for plan.md
219
+ */
220
+ content: string;
221
+ }
222
+ export interface SessionPlanDeleteResult {
223
+ }
224
+ export interface SessionPlanDeleteParams {
225
+ /**
226
+ * Target session identifier
227
+ */
228
+ sessionId: string;
229
+ }
230
+ export interface SessionWorkspaceListFilesResult {
231
+ /**
232
+ * Relative file paths in the workspace files directory
233
+ */
234
+ files: string[];
235
+ }
236
+ export interface SessionWorkspaceListFilesParams {
237
+ /**
238
+ * Target session identifier
239
+ */
240
+ sessionId: string;
241
+ }
242
+ export interface SessionWorkspaceReadFileResult {
243
+ /**
244
+ * File content as a UTF-8 string
245
+ */
246
+ content: string;
247
+ }
248
+ export interface SessionWorkspaceReadFileParams {
249
+ /**
250
+ * Target session identifier
251
+ */
252
+ sessionId: string;
253
+ /**
254
+ * Relative path within the workspace files directory
255
+ */
256
+ path: string;
257
+ }
258
+ export interface SessionWorkspaceCreateFileResult {
259
+ }
260
+ export interface SessionWorkspaceCreateFileParams {
261
+ /**
262
+ * Target session identifier
263
+ */
264
+ sessionId: string;
265
+ /**
266
+ * Relative path within the workspace files directory
267
+ */
268
+ path: string;
269
+ /**
270
+ * File content to write as a UTF-8 string
271
+ */
272
+ content: string;
273
+ }
274
+ export interface SessionFleetStartResult {
275
+ /**
276
+ * Whether fleet mode was successfully activated
277
+ */
278
+ started: boolean;
279
+ }
280
+ export interface SessionFleetStartParams {
281
+ /**
282
+ * Target session identifier
283
+ */
284
+ sessionId: string;
285
+ /**
286
+ * Optional user prompt to combine with fleet instructions
287
+ */
288
+ prompt?: string;
289
+ }
290
+ /** Create typed server-scoped RPC methods (no session required). */
291
+ export declare function createServerRpc(connection: MessageConnection): {
292
+ ping: (params: PingParams) => Promise<PingResult>;
293
+ models: {
294
+ list: () => Promise<ModelsListResult>;
295
+ };
296
+ tools: {
297
+ list: (params: ToolsListParams) => Promise<ToolsListResult>;
298
+ };
299
+ account: {
300
+ getQuota: () => Promise<AccountGetQuotaResult>;
301
+ };
302
+ };
303
+ /** Create typed session-scoped RPC methods. */
304
+ export declare function createSessionRpc(connection: MessageConnection, sessionId: string): {
305
+ model: {
306
+ getCurrent: () => Promise<SessionModelGetCurrentResult>;
307
+ switchTo: (params: Omit<SessionModelSwitchToParams, "sessionId">) => Promise<SessionModelSwitchToResult>;
308
+ };
309
+ mode: {
310
+ get: () => Promise<SessionModeGetResult>;
311
+ set: (params: Omit<SessionModeSetParams, "sessionId">) => Promise<SessionModeSetResult>;
312
+ };
313
+ plan: {
314
+ read: () => Promise<SessionPlanReadResult>;
315
+ update: (params: Omit<SessionPlanUpdateParams, "sessionId">) => Promise<SessionPlanUpdateResult>;
316
+ delete: () => Promise<SessionPlanDeleteResult>;
317
+ };
318
+ workspace: {
319
+ listFiles: () => Promise<SessionWorkspaceListFilesResult>;
320
+ readFile: (params: Omit<SessionWorkspaceReadFileParams, "sessionId">) => Promise<SessionWorkspaceReadFileResult>;
321
+ createFile: (params: Omit<SessionWorkspaceCreateFileParams, "sessionId">) => Promise<SessionWorkspaceCreateFileResult>;
322
+ };
323
+ fleet: {
324
+ start: (params: Omit<SessionFleetStartParams, "sessionId">) => Promise<SessionFleetStartResult>;
325
+ };
326
+ };
@@ -0,0 +1,43 @@
1
+ function createServerRpc(connection) {
2
+ return {
3
+ ping: async (params) => connection.sendRequest("ping", params),
4
+ models: {
5
+ list: async () => connection.sendRequest("models.list", {})
6
+ },
7
+ tools: {
8
+ list: async (params) => connection.sendRequest("tools.list", params)
9
+ },
10
+ account: {
11
+ getQuota: async () => connection.sendRequest("account.getQuota", {})
12
+ }
13
+ };
14
+ }
15
+ function createSessionRpc(connection, sessionId) {
16
+ return {
17
+ model: {
18
+ getCurrent: async () => connection.sendRequest("session.model.getCurrent", { sessionId }),
19
+ switchTo: async (params) => connection.sendRequest("session.model.switchTo", { sessionId, ...params })
20
+ },
21
+ mode: {
22
+ get: async () => connection.sendRequest("session.mode.get", { sessionId }),
23
+ set: async (params) => connection.sendRequest("session.mode.set", { sessionId, ...params })
24
+ },
25
+ plan: {
26
+ read: async () => connection.sendRequest("session.plan.read", { sessionId }),
27
+ update: async (params) => connection.sendRequest("session.plan.update", { sessionId, ...params }),
28
+ delete: async () => connection.sendRequest("session.plan.delete", { sessionId })
29
+ },
30
+ workspace: {
31
+ listFiles: async () => connection.sendRequest("session.workspace.listFiles", { sessionId }),
32
+ readFile: async (params) => connection.sendRequest("session.workspace.readFile", { sessionId, ...params }),
33
+ createFile: async (params) => connection.sendRequest("session.workspace.createFile", { sessionId, ...params })
34
+ },
35
+ fleet: {
36
+ start: async (params) => connection.sendRequest("session.fleet.start", { sessionId, ...params })
37
+ }
38
+ };
39
+ }
40
+ export {
41
+ createServerRpc,
42
+ createSessionRpc
43
+ };
@@ -1,13 +1,6 @@
1
1
  /**
2
2
  * AUTO-GENERATED FILE - DO NOT EDIT
3
- *
4
- * Generated from: @github/copilot/session-events.schema.json
5
- * Generated by: scripts/generate-session-types.ts
6
- * Generated at: 2026-02-06T20:38:23.139Z
7
- *
8
- * To update these types:
9
- * 1. Update the schema in copilot-agent-runtime
10
- * 2. Run: npm run generate:session-types
3
+ * Generated from: session-events.schema.json
11
4
  */
12
5
  export type SessionEvent = {
13
6
  id: string;
@@ -65,6 +58,15 @@ export type SessionEvent = {
65
58
  ephemeral: true;
66
59
  type: "session.idle";
67
60
  data: {};
61
+ } | {
62
+ id: string;
63
+ timestamp: string;
64
+ parentId: string | null;
65
+ ephemeral: true;
66
+ type: "session.title_changed";
67
+ data: {
68
+ title: string;
69
+ };
68
70
  } | {
69
71
  id: string;
70
72
  timestamp: string;
@@ -75,6 +77,16 @@ export type SessionEvent = {
75
77
  infoType: string;
76
78
  message: string;
77
79
  };
80
+ } | {
81
+ id: string;
82
+ timestamp: string;
83
+ parentId: string | null;
84
+ ephemeral?: boolean;
85
+ type: "session.warning";
86
+ data: {
87
+ warningType: string;
88
+ message: string;
89
+ };
78
90
  } | {
79
91
  id: string;
80
92
  timestamp: string;
@@ -85,6 +97,38 @@ export type SessionEvent = {
85
97
  previousModel?: string;
86
98
  newModel: string;
87
99
  };
100
+ } | {
101
+ id: string;
102
+ timestamp: string;
103
+ parentId: string | null;
104
+ ephemeral?: boolean;
105
+ type: "session.mode_changed";
106
+ data: {
107
+ previousMode: string;
108
+ newMode: string;
109
+ };
110
+ } | {
111
+ id: string;
112
+ timestamp: string;
113
+ parentId: string | null;
114
+ ephemeral?: boolean;
115
+ type: "session.plan_changed";
116
+ data: {
117
+ operation: "create" | "update" | "delete";
118
+ };
119
+ } | {
120
+ id: string;
121
+ timestamp: string;
122
+ parentId: string | null;
123
+ ephemeral?: boolean;
124
+ type: "session.workspace_file_changed";
125
+ data: {
126
+ /**
127
+ * Relative path within the workspace files directory
128
+ */
129
+ path: string;
130
+ operation: "create" | "update";
131
+ };
88
132
  } | {
89
133
  id: string;
90
134
  timestamp: string;
@@ -162,6 +206,18 @@ export type SessionEvent = {
162
206
  };
163
207
  currentModel?: string;
164
208
  };
209
+ } | {
210
+ id: string;
211
+ timestamp: string;
212
+ parentId: string | null;
213
+ ephemeral?: boolean;
214
+ type: "session.context_changed";
215
+ data: {
216
+ cwd: string;
217
+ gitRoot?: string;
218
+ repository?: string;
219
+ branch?: string;
220
+ };
165
221
  } | {
166
222
  id: string;
167
223
  timestamp: string;
@@ -217,10 +273,18 @@ export type SessionEvent = {
217
273
  type: "file";
218
274
  path: string;
219
275
  displayName: string;
276
+ lineRange?: {
277
+ start: number;
278
+ end: number;
279
+ };
220
280
  } | {
221
281
  type: "directory";
222
282
  path: string;
223
283
  displayName: string;
284
+ lineRange?: {
285
+ start: number;
286
+ end: number;
287
+ };
224
288
  } | {
225
289
  type: "selection";
226
290
  filePath: string;
@@ -238,6 +302,7 @@ export type SessionEvent = {
238
302
  };
239
303
  })[];
240
304
  source?: string;
305
+ agentMode?: "interactive" | "plan" | "autopilot" | "shell";
241
306
  };
242
307
  } | {
243
308
  id: string;
@@ -302,6 +367,7 @@ export type SessionEvent = {
302
367
  reasoningOpaque?: string;
303
368
  reasoningText?: string;
304
369
  encryptedContent?: string;
370
+ phase?: string;
305
371
  parentToolCallId?: string;
306
372
  };
307
373
  } | {
@@ -423,6 +489,48 @@ export type SessionEvent = {
423
489
  result?: {
424
490
  content: string;
425
491
  detailedContent?: string;
492
+ contents?: ({
493
+ type: "text";
494
+ text: string;
495
+ } | {
496
+ type: "terminal";
497
+ text: string;
498
+ exitCode?: number;
499
+ cwd?: string;
500
+ } | {
501
+ type: "image";
502
+ data: string;
503
+ mimeType: string;
504
+ } | {
505
+ type: "audio";
506
+ data: string;
507
+ mimeType: string;
508
+ } | {
509
+ icons?: {
510
+ src: string;
511
+ mimeType?: string;
512
+ sizes?: string[];
513
+ theme?: "light" | "dark";
514
+ }[];
515
+ name: string;
516
+ title?: string;
517
+ uri: string;
518
+ description?: string;
519
+ mimeType?: string;
520
+ size?: number;
521
+ type: "resource_link";
522
+ } | {
523
+ type: "resource";
524
+ resource: {
525
+ uri: string;
526
+ mimeType?: string;
527
+ text: string;
528
+ } | {
529
+ uri: string;
530
+ mimeType?: string;
531
+ blob: string;
532
+ };
533
+ })[];
426
534
  };
427
535
  error?: {
428
536
  message: string;
@@ -466,6 +574,7 @@ export type SessionEvent = {
466
574
  data: {
467
575
  toolCallId: string;
468
576
  agentName: string;
577
+ agentDisplayName: string;
469
578
  };
470
579
  } | {
471
580
  id: string;
@@ -476,6 +585,7 @@ export type SessionEvent = {
476
585
  data: {
477
586
  toolCallId: string;
478
587
  agentName: string;
588
+ agentDisplayName: string;
479
589
  error: string;
480
590
  };
481
591
  } | {
package/dist/index.d.ts CHANGED
@@ -6,4 +6,4 @@
6
6
  export { CopilotClient } from "./client.js";
7
7
  export { CopilotSession, type AssistantMessageEvent } from "./session.js";
8
8
  export { defineTool } from "./types.js";
9
- export type { ConnectionState, CopilotClientOptions, CustomAgentConfig, ForegroundSessionInfo, GetAuthStatusResponse, GetStatusResponse, InfiniteSessionConfig, MCPLocalServerConfig, MCPRemoteServerConfig, MCPServerConfig, MessageOptions, ModelBilling, ModelCapabilities, ModelInfo, ModelPolicy, PermissionHandler, PermissionRequest, PermissionRequestResult, ResumeSessionConfig, SessionConfig, SessionEvent, SessionEventHandler, SessionEventPayload, SessionEventType, SessionLifecycleEvent, SessionLifecycleEventType, SessionLifecycleHandler, SessionMetadata, SystemMessageAppendConfig, SystemMessageConfig, SystemMessageReplaceConfig, Tool, ToolHandler, ToolInvocation, ToolResultObject, TypedSessionEventHandler, TypedSessionLifecycleHandler, ZodSchema, } from "./types.js";
9
+ export type { ConnectionState, CopilotClientOptions, CustomAgentConfig, ForegroundSessionInfo, GetAuthStatusResponse, GetStatusResponse, InfiniteSessionConfig, MCPLocalServerConfig, MCPRemoteServerConfig, MCPServerConfig, MessageOptions, ModelBilling, ModelCapabilities, ModelInfo, ModelPolicy, PermissionHandler, PermissionRequest, PermissionRequestResult, ResumeSessionConfig, SessionConfig, SessionEvent, SessionEventHandler, SessionEventPayload, SessionEventType, SessionLifecycleEvent, SessionLifecycleEventType, SessionLifecycleHandler, SessionContext, SessionListFilter, SessionMetadata, SystemMessageAppendConfig, SystemMessageConfig, SystemMessageReplaceConfig, Tool, ToolHandler, ToolInvocation, ToolResultObject, TypedSessionEventHandler, TypedSessionLifecycleHandler, ZodSchema, } from "./types.js";
package/dist/session.d.ts CHANGED
@@ -3,6 +3,7 @@
3
3
  * @module session
4
4
  */
5
5
  import type { MessageConnection } from "vscode-jsonrpc/node";
6
+ import { createSessionRpc } from "./generated/rpc.js";
6
7
  import type { MessageOptions, PermissionHandler, PermissionRequestResult, SessionEvent, SessionEventHandler, SessionEventType, SessionHooks, Tool, ToolHandler, TypedSessionEventHandler, UserInputHandler, UserInputResponse } from "./types.js";
7
8
  /** Assistant message event - the final response from the assistant. */
8
9
  export type AssistantMessageEvent = Extract<SessionEvent, {
@@ -43,6 +44,7 @@ export declare class CopilotSession {
43
44
  private permissionHandler?;
44
45
  private userInputHandler?;
45
46
  private hooks?;
47
+ private _rpc;
46
48
  /**
47
49
  * Creates a new CopilotSession instance.
48
50
  *
@@ -52,6 +54,10 @@ export declare class CopilotSession {
52
54
  * @internal This constructor is internal. Use {@link CopilotClient.createSession} to create sessions.
53
55
  */
54
56
  constructor(sessionId: string, connection: MessageConnection, _workspacePath?: string | undefined);
57
+ /**
58
+ * Typed session-scoped RPC methods.
59
+ */
60
+ get rpc(): ReturnType<typeof createSessionRpc>;
55
61
  /**
56
62
  * Path to the session workspace directory when infinite sessions are enabled.
57
63
  * Contains checkpoints/, plan.md, and files/ subdirectories.
package/dist/session.js CHANGED
@@ -1,3 +1,4 @@
1
+ import { createSessionRpc } from "./generated/rpc.js";
1
2
  class CopilotSession {
2
3
  /**
3
4
  * Creates a new CopilotSession instance.
@@ -18,6 +19,16 @@ class CopilotSession {
18
19
  permissionHandler;
19
20
  userInputHandler;
20
21
  hooks;
22
+ _rpc = null;
23
+ /**
24
+ * Typed session-scoped RPC methods.
25
+ */
26
+ get rpc() {
27
+ if (!this._rpc) {
28
+ this._rpc = createSessionRpc(this.connection, this.sessionId);
29
+ }
30
+ return this._rpc;
31
+ }
21
32
  /**
22
33
  * Path to the session workspace directory when infinite sessions are enabled.
23
34
  * Contains checkpoints/, plan.md, and files/ subdirectories.
package/dist/types.d.ts CHANGED
@@ -695,6 +695,32 @@ export type SessionEventHandler = (event: SessionEvent) => void;
695
695
  * Connection state
696
696
  */
697
697
  export type ConnectionState = "disconnected" | "connecting" | "connected" | "error";
698
+ /**
699
+ * Working directory context for a session
700
+ */
701
+ export interface SessionContext {
702
+ /** Working directory where the session was created */
703
+ cwd: string;
704
+ /** Git repository root (if in a git repo) */
705
+ gitRoot?: string;
706
+ /** GitHub repository in "owner/repo" format */
707
+ repository?: string;
708
+ /** Current git branch */
709
+ branch?: string;
710
+ }
711
+ /**
712
+ * Filter options for listing sessions
713
+ */
714
+ export interface SessionListFilter {
715
+ /** Filter by exact cwd match */
716
+ cwd?: string;
717
+ /** Filter by git root */
718
+ gitRoot?: string;
719
+ /** Filter by repository (owner/repo format) */
720
+ repository?: string;
721
+ /** Filter by branch */
722
+ branch?: string;
723
+ }
698
724
  /**
699
725
  * Metadata about a session
700
726
  */
@@ -704,6 +730,8 @@ export interface SessionMetadata {
704
730
  modifiedTime: Date;
705
731
  summary?: string;
706
732
  isRemote: boolean;
733
+ /** Working directory context (cwd, git info) from session creation */
734
+ context?: SessionContext;
707
735
  }
708
736
  /**
709
737
  * Response from status.get
package/package.json CHANGED
@@ -4,7 +4,7 @@
4
4
  "type": "git",
5
5
  "url": "https://github.com/github/copilot-sdk.git"
6
6
  },
7
- "version": "0.1.24-preview.0",
7
+ "version": "0.1.25-preview.0",
8
8
  "description": "TypeScript SDK for programmatic control of GitHub Copilot CLI via JSON-RPC",
9
9
  "main": "./dist/index.js",
10
10
  "types": "./dist/index.d.ts",
@@ -25,7 +25,7 @@
25
25
  "lint": "eslint \"src/**/*.ts\" \"test/**/*.ts\"",
26
26
  "lint:fix": "eslint --fix \"src/**/*.ts\" \"test/**/*.ts\"",
27
27
  "typecheck": "tsc --noEmit",
28
- "generate:session-types": "tsx scripts/generate-session-types.ts",
28
+ "generate": "cd ../scripts/codegen && npm run generate",
29
29
  "update:protocol-version": "tsx scripts/update-protocol-version.ts",
30
30
  "prepublishOnly": "npm run build",
31
31
  "package": "npm run clean && npm run build && node scripts/set-version.js && npm pack && npm version 0.1.0 --no-git-tag-version --allow-same-version"
@@ -40,7 +40,7 @@
40
40
  "author": "GitHub",
41
41
  "license": "MIT",
42
42
  "dependencies": {
43
- "@github/copilot": "^0.0.405",
43
+ "@github/copilot": "^0.0.411-1",
44
44
  "vscode-jsonrpc": "^8.2.1",
45
45
  "zod": "^4.3.6"
46
46
  },
@@ -62,7 +62,7 @@
62
62
  "vitest": "^4.0.18"
63
63
  },
64
64
  "engines": {
65
- "node": ">=24.0.0"
65
+ "node": ">=20.0.0"
66
66
  },
67
67
  "files": [
68
68
  "dist/**/*",